python: законно ли передавать self во вложенную функцию внутри метода класса?

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)

Мой первый вопрос - законно ли проходить selfпараметр вложенной функции метода класса? Я запускаю этот код на python-3.5.2 без проблем, и обаprint()отображать тот же адрес экземпляра класса A. Однако python-3.6 жалуется онлайнprint(self, self.a, self.b) который self не имеет члена a.

Также интересно то, что PyCharm IDE не выделяет self на этой строчке и говорит, что она "затмевает внешний вид".

Что именно я делаю не так?

1 ответ

Решение

Любая функция, определенная в области видимости, может использовать переменные из окружающей области. В этом случае вы определяете функцию внутри функции, поэтому доступны все переменные во включающей функции -self, param1, and param2. Так ты можешь пройтиself как параметр внутренней функции, но поскольку он уже имеет доступ к self, в этом нет особого смысла.

Если вы создаете новые переменные с этими именами внутри своей новой функции, они "затеняют" переменные с этими именами во внешней области, то есть имена из внешней области недоступны, пока те же имена относятся к чему-то еще во внутренней области.. self - это просто обычное имя переменной без особого значения, за исключением того, что это первый параметр функции экземпляра класса, и поэтому он передается неявно, когда метод вызывается через оператор точки, что означает, что он подчиняется этим правилам.

Во внутренней функции вы передаете self явно, что безвредно, но в данном случае также бессмысленно. Python 3.6 (и Pycharm) выдает предупреждения, потому что он не может выполнять проверку типов, но это все.

Другими словами, это будет работать так же хорошо и не вызовет ошибок:

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

    inner_func1()
Другие вопросы по тегам