【发布时间】:2020-12-06 20:36:00
【问题描述】:
我似乎对 Python 变量绑定有误解。给定具有阴影名称的嵌套范围,确定访问哪个变量的精确规则是什么?
让我用一些例子来说明。首先是基本阴影。
a = 1
def foo():
a = 2
def _foo():
return a
return _foo()
print(foo()) # -> 2
这里一切都很好。该值被覆盖并相应地返回。但是,如果在函数定义之后改变了值,它仍然是内部值:
def bar():
def _bar():
return a
a = 2
return _bar()
print(bar()) # -> 2
此外,定义一个引用不存在变量的函数是可能的。
def baz():
def _baz():
return b
return _baz()
那么,如果后面定义了b,就可以执行函数了。 但如果在另一个内部范围中定义则不行:
def qux(f):
b = 3
return f()
print(qux(baz())) # -> NameError
现在,所有这些情况都可以通过让 Python 了解程序后面的行来解释,但这与我对 Python 是一种解释性语言、逐行推进的知识相冲突。那么语句是一次解析而不是逐行解析吗?
一个带有阴影类属性的奇怪行为让我更加反感。
class C:
a = 2
b = a
def meth(self):
return a
c = meth
print(C.b, C().meth(), C.c) # -> 2 1 C.meth
这里a被定义为一个类属性,并在b中成功使用,但这并没有延续到方法定义中。方法本身可以在后面的属性中使用,但不能在其他方法中使用,例如不经过self。
我对绑定同时发生的猜测是否正确?在那种情况下,类主体是设计上的例外,还是根本不是范围?还是这里发生了其他事情?
【问题讨论】:
-
stackoverflow.com/questions/291978/… 的前两个答案应该可以回答您的问题。请注意,“封闭”是指“在内部定义”,而不是“被调用”。
-
@ThierryLathuille 非常感谢!