1

Here I defined a class with custom ___mul__ operator. Inside the __mul__ operator I define a _backward function that use an argument to that function (other variable ).

How does python keep track of the other variable when I call the _backward function on out.

Does it internally keep track of the scope in which the function is defined?

class Value:
    
    def __init__(self, data):
        self.data = data
        self.__rmul__ = self.__mul__
        
    def __mul__(self, other):
        out = Value(self.data*other.data)
        
        def _backward():
            print('Backward of ', self.data, other.data)
            
            
        out._backward = _backward
        return out
        
    def __rmul__(self, other):
        self.__mul__(self, other)

a = Value(10)
b = Value(5)

o = a*b

o._backward()

Output:

Backward of  10 5
1
  • 1
    its part of the closure Commented Oct 30, 2022 at 0:08

1 Answer 1

1

In Python, first, it will check if there is a local variable (local to _backward function) called other. Then it will check in the outer scope which is __mul__, then it will check in the global scope, i.e., a variable declared in the zero level of indentation.

local variable to _backward

class Value:
    ...
    
    def __mul__(self, other):
        out = Value(self.data*other.data)
        
        def _backward():
            other =  Value(20)
            print('Backward of ', self.data, other.data)
            
            
        out._backward = _backward
        return out

Output:

Backward of  10 20

other is a local variable to __mul__

This is the code you are showing.

Sign up to request clarification or add additional context in comments.

5 Comments

Interesting, so each call to __mul__ has its own new persisted scope? So if I make 10,000 __mul__ calls, python will keep track of 10,000 scopes till the program ends.
@Saurabh7, correct, whenever __mul__ is called, it will create a new scope which will disappear when the call ends. In fact, that is what happens in any function call.
But the scope is still there after a*b is ended. I call o._backward() after and its still works later.
__mul__ will be called when you execute a*b, and the value of other will set at that moment. Any time you call _backward, it will have the value that was set when a * b was executed.
@Saurabh7 no, just as long as the function object exists

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.