Reputation: 353
I'm learning python and I came across the code for the Fraction below. The Fraction class has an __add__
method whose return calls the Fraction class.
(return Fraction(new_num // common, new_den // common)
).
I don't really get how a method can call the class it's a part of. I mean the interpreter hasn't even fully finished reading the Fraction class (there's still the __eq__
method after the __add__
method) when the __add__
method calls the Fraction class. What if the __add__
method wanted to use the classes __eq__
method when the __eq__
method is below it?
class Fraction:
def __init__(self, top, bottom):
self.num = top
self.den = bottom
def __str__(self):
return str(self.num) + "/" + str(self.den)
def show(self):
print(self.num, "/", self.den)
def __add__(self, other_fraction):
new_num = self.num * other_fraction.den + \
self.den * other_fraction.num
new_den = self.den * other_fraction.den
common = gcd(new_num, new_den)
return Fraction(new_num // common, new_den // common)
def __eq__(self, other):
first_num = self.num * other.den
second_num = other.num * self.den
return first_num == second_num
Upvotes: 3
Views: 89
Reputation: 78750
I mean the interpreter hasn't even fully finished reading the Fraction class
It has already been parsed and executed when you execute __add__
for the first time. Function and method bodies are not executed on import time, but class bodies (even nested class bodies) are.
Demo script:
class Upper:
print('Upper')
class Mid:
print('Mid')
def method(self):
class Low:
print('Low')
print('method')
Output:
$ python3
>>> import demo
Upper
Mid
For this reason, it is not an error to refer to the class of a method within that method (because the method is not called during class construction).
On the other hand, you can't access the name of a class while it is still being built within the parts that are executed during import time.
>>> class A:
... print(A)
...
[...]
NameError: name 'A' is not defined
Upvotes: 2
Reputation: 83557
return Fraction(new_num // common, new_den // common)
What you refer to as "calling the Fraction class" actually creates a new instance of Fraction
with the given numerator and denominator. If you are familiar with Java, this is equivalent to return new Fraction(...)
. In Python, we don't use the keyword new
.
I mean the interpreter hasn't even fully finished reading the Fraction class
When this line is parsed, the interpreter knows that the Fraction
class exists, which is sufficient at that time. By the time the line is executed with a call the __add__()
function on an instance of Fraction
, the entire Fraction
class is available to the interpreter.
What if the
__add__
method wanted to use the classes__eq__
method when the__eq__
method is below it?
This is perfectly fine because by the time that the body of the method is executed, the __eq__
method has been recognized and made available to be called.
Upvotes: 0