我正在学习Python,现在我正在讨论范围和非本地语句的主题。 在某个时候,我以为我已经搞定了,但后来外地人来了,把一切都搞砸了。在
示例1:
print( "let's begin" )
def a():
def b():
nonlocal x
x = 20
b()
a()
运行它自然会失败。
更有趣的是,print(
)没有被执行。为什么?在
我的理解是,封闭def a()
直到print()
才执行,而嵌套的{a()
时执行。我很困惑。。。在
好的,让我们来看看例子2:
^{pr2}$啊还有。。。它运行良好。
什么?!那是怎么解决的?^函数a
中的{
我的理解是在运行时计算和执行非本地语句,搜索封闭函数的调用上下文,并将本地名称x
绑定到某个特定的“outer”x
。如果外部函数中没有x
,则引发异常。再次,在运行时。在
但现在看来这是在语法分析时完成的,使用相当愚蠢的检查“lookinouterfunctions for x = blah
,如果有类似的东西-我们很好”,即使{
有谁能解释一下非本地语句是何时以及如何处理的吗?在
首先,要明白python将检查模块的语法,如果它检测到无效的内容,它会发出一个
SyntaxError
,这会完全停止它的运行。您的第一个例子提出了一个SyntaxError
,但是要确切地理解原因是相当复杂的,尽管如果您知道__slots__
是如何工作的,那么就更容易理解了,所以我将首先快速介绍这一点。在当一个类定义
__slots__
时,它基本上是说实例应该只具有那些属性,这样每个对象都被分配了内存,只为这些属性分配空间,试图分配其他属性会引发错误x.c = 3
不能工作的原因是没有内存空间来放置.c
属性。在如果不指定
^{pr2}$__slots__
,则所有实例都是用字典创建的,以存储实例变量,字典对它们包含的值没有任何限制Python函数的工作原理类似于
slots
。当python检查模块的语法时,它会在每个函数定义中找到分配(或试图分配)的所有变量,并在执行期间构造框架时使用这些变量。在当您使用
nonlocal x
时,它给了一个内部函数访问外部函数作用域中的特定变量,但是如果外部函数中没有定义变量,则nonlocal x
就没有空间可指向。全局访问不会遇到相同的问题,因为python模块是用字典来存储其属性的。因此,即使没有对
x
的全局引用,也允许global x
您可以从
a
的作用域中了解b
对自由变量(可用于绑定)的了解,如下所示:它给出了:
^{pr2}$如果您注释掉
nonlocal
行,并删除if
语句,其中包含x
,您将看到b
可用的自由变量只是()
。在让我们看看这生成了什么字节码指令,通过将
a
的定义放入IPython,然后使用dis.dis
:那么让我们看看how ^{} is processed in ^{} 。在
所以我们看到它必须从封闭作用域的
x
查找x
。在这里提到的是in the Execution Model documentation,它说:
相关问题 更多 >
编程相关推荐