【问题标题】:python: is it legal to pass self to the nested function inside the class method?python:将self传递给类方法内的嵌套函数是否合法?
【发布时间】:2020-06-29 14:06:31
【问题描述】:
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,并说它“超出了外部范围”。

我到底做错了什么?

【问题讨论】:

  • Python 3.6 运行这段代码对我来说很好。你确定这是 Python 错误,而不是 PyCharm 错误/警告?
  • 实例方法的第一个参数的唯一特别之处(名称self 只是传统的,不是必需的)是您不必提供显式参数。描述符协议允许您编写 a.func(1,2) 而不是 type(a).func(a, 1, 2)

标签: python python-3.x python-class


【解决方案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()

【讨论】:

    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多