【问题标题】:why this instance variable assignment in class method not cause UnboundLocalError in Python为什么类方法中的这个实例变量赋值不会导致 Python 中的 UnboundLocalError
【发布时间】:2021-07-12 01:29:27
【问题描述】:

在下面的代码中,如果在函数 foo 中对名称 v 使用赋值语句,解释器会给出 unboundlocalerror,因为这会在函数范围内创建一个同名变量,我们会在本地赋值之前尝试引用它。但是为什么在实例方法中的实例变量上做同样的事情没有给出任何错误呢? Python评估self.v = self.v + 1v = v + 1时有什么区别?

class A:
    v = 1
    def foo(self):
        self.v = self.v + 1
v = 1
def foo():
    v = v + 1

# UnboundLocalError: local variable 'v' referenced before assignment
foo()

a = A()
# print 1
print(a.v)
a.foo()
# print 1 2
print(a.__class__.v, a.v)

【问题讨论】:

  • 因为self 已定义而v 未定义。

标签: python variable-assignment


【解决方案1】:

局部变量解析是静态的。在字节码编译时,Python 会识别出foo 有一个v 局部变量,因此所有对foo 中的v 的访问都会转到局部变量,即使局部变量未绑定。

实例属性解析是动态的。每当执行self.v 访问时,Python 都会搜索继承层次结构中的实例字典和类字典,以确定v 应该是什么。 (不过,除非定义了其他一些自定义行为,否则分配总是转到实例字典。)

与局部变量不同,self.v 的赋值本身并不影响属性访问解析为什么,self.v 的重复访问可能会以不同的方式解析;一次访问可能在实例字典中找不到任何内容并解析为类字典中的'v' 条目,而稍后的条目可能会发现此时实例字典中存在'v' 条目,并解决此问题。

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2020-12-18
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    相关资源
    最近更新 更多