ghost
ghost

Reputation: 1207

Resolving private attributes in a derived class

Suppose I have a base class Circle which has a perimeter function, and a derived class Tire. The following is the code:

import math

class Circle(object):
    
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        p = self.__perimeter()
        return math.pi * (p *0.5/math.pi)**2 

    def perimeter(self):
        return self.__perimeter()
    
    def __perimeter(self):
        return 2.0 * math.pi * self.radius

And the class Tire:

class Tire(Circle):
    def perimeter(self):
        return self.__perimeter()
    def __perimeter(self):
        return Circle.perimeter(self)*1.25

I know that any attribute with __ in beginning is resolved to _classname.__attribute, so __perimeter in Circle would resolve to _Circle.__perimeter.

So if I run the following code, what would be the flow:

t = Tire(20)
print(t.area())

What I believed was t.area() would call self.__perimeter() which would be resolved to Tire._Tire__perimeter, but that isn't compliant with the answer I got.

So basically it boils down to, how is self resolved?

Can someone please explain the flow behind this?

PS: This doubt is based on a presentation video by Raymond Hettinger.

Upvotes: 0

Views: 38

Answers (1)

0Interest
0Interest

Reputation: 1842

The method __perimeter in the Tire class does not get called when you call t.area(), but calling the method perimeter in the class Circle. By this, you do not call self.__perimeter() (Beware of the self - it is has type Tire thus calling the tire perimeter method)

So when you call t.area() you do not access this via t_Tire__perimeter() - because this is how you would access the private perimeter function in the Tire class. (~157.079) Which in code is basically:

t = Tire(20)
print(t.perimeter())

The flow is as so:

  • Creating a new object of type Tire - which its superclass is Circle
  • Calling t.area()
  • In the area method - self is still of type Tire as seen in (*)
  • Inside area - self.__perimeter() is called thus calling _Circle__perimeter

Upvotes: 1

Related Questions