Whooey
Whooey

Reputation: 31

How can a nested function change an instance variable of its enclosing function?

I was practicing LeetCode and got confused on the scope of self for a solution. I thought that self is a local variable to diameterOfBinaryTree(), so the nested function height() should only be able to read self.ans and not modify it, according to LEGB scoping rule. So how can height() modify self.ans in this solution? Thanks!

P.S. I couldn't get "class Solution(object):" to format correctly so just assume that the indentation is correct.

class Solution(object):
def diameterOfBinaryTree(self, root):

    self.ans = 0
    
    def height(p):
        if not p: return -1       
                        
        left, right = height(p.left), height(p.right)
        
        self.ans = max(self.ans, 2+left+right)   
        
        return 1+max(left, right)
        
    height(root)
    return self.ans

Upvotes: 2

Views: 81

Answers (1)

Mad Physicist
Mad Physicist

Reputation: 114330

Most of your reasoning is correct, except for one thing: self.ans = ... is not rebinding anything in the non-local scope. Instead, the .= operator is syntactic sugar for setattr(self, 'ans', ...). Clearly the function call does not violate LEGB in any way, since the reference to self is read-only.

For perhaps an easier example, consider the difference between some_list.extend([1, 2, 3]) vs some_list += [1, 2, 3]. The former is a method call that happens to modify a mutable object, while the latter attempts to reassign the reference.

Upvotes: 2

Related Questions