user3124200
user3124200

Reputation: 353

How can a method call the class which it's a member of in python?

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

Answers (2)

timgeb
timgeb

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

Code-Apprentice
Code-Apprentice

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

Related Questions