Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: is it legal to pass self to the nested function inside the class method?

class A:
    def __init__(self):
        self.name = None
        self.a = 10
        self.b = 20
        self.c = 30
    def func1(self, param1, param2):
        def inner_func1(self, param1, param2):
            print(self, self.a, self.b)

        inner_func1(self, param1, param2)

a = A()
print(a)
a.func1(1,2)

My first question -- is it legal to pass self parameter to the class method's nested function? I run this code on python-3.5.2 with no problems, and both print() display the same address of the class A instance. However python-3.6 complains on line print(self, self.a, self.b) that self has no member a.

Also interesting is that PyCharm IDE does not highlight self on this line, and says that it "outshades the outer scope".

What exactly am I doing wrong?

like image 205
Mark Avatar asked Mar 03 '23 16:03

Mark


1 Answers

Any function defined within a scope can use variables from its enclosing scope. In this case, you're defining a function within a function, so all the variables in the enclosing function are available - self, param1, and param2. So you can pass self as a parameter to the inner function, but since it already has access to self, there's not much point to doing so.

If you create new variables with these names inside your new function, they "shadow" the variables with those names in the outer scope, meaning the names from the outer scope are inaccessible as long as the same names refer to something else in the inner scope. self is just a normal variable name with no special meaning, except that it's the first parameter of a class's instance function, and thus gets passed implicitly when the method is called via the dot operator - meaning that it's subject to these rules.

In your inner function, you're passing self explicitly, which is harmless but also pointless in this case. Python 3.6 (and Pycharm) is giving you warnings because it can't do typechecking on this, but that's all.

In other words, this would work just as well and cause no errors:

def func1(self, param1, param2):
    def inner_func1():
        print(self, self.a, self.b)

    inner_func1()
like image 141
Green Cloak Guy Avatar answered Apr 29 '23 12:04

Green Cloak Guy