我正在学习Python,现在我正在讨论范围和非本地语句。在某个时候,我以为我想通了一切,但是后来非本地人来了,把一切都分解了。
示例1:
print( "let's begin" )
def a():
def b():
nonlocal x
x = 20
b()
a()
运行它自然会失败。
更有趣的是print(
)没有执行。为什么?。
我的理解是,封闭def a()
不执行之前print()
执行,并嵌套def b()
时,才会执行a()
被调用。我很迷惑…
好,让我们尝试示例2:
print( "let's begin" )
def a():
if False: x = 10
def b():
nonlocal x
x = 20
b()
a()
Aaand …运行良好。哇!!它是如何解决的?x = 10
功能a
永远不会执行!
我的理解是,非本地语句是在运行时评估和执行的,它搜索封闭函数的调用上下文,并将本地名称绑定x
到某些特定的“外部” x
。如果x
外部函数没有-
引发异常。同样,在运行时。
但是现在看来,这似乎是在语法分析时完成的,只需进行愚蠢的检查,“检查外部函数x = blah
是否存在,如果这样的话-我们很好,”即使x = blah
从未执行过…
谁能解释我何时以及如何处理非本地语句?
您可以从的范围中看到b
有关自由变量(可用于绑定)的了解范围a
,如下所示:
import inspect
print( "let's begin" )
def a():
if False:
x = 10
def b():
print(inspect.currentframe().f_code.co_freevars)
nonlocal x
x = 20
b()
a()
这使:
let's begin
('x',)
如果您注释掉该nonlocal
行,并删除其中的if
语句,x
则会看到可供使用的自由变量b
is ()
。
因此,让我们看一下它生成的字节码指令,方法是将的定义a
放入IPython中,然后使用dis.dis
:
In [3]: import dis
In [4]: dis.dis(a)
5 0 LOAD_CLOSURE 0 (x)
2 BUILD_TUPLE 1
4 LOAD_CONST 1 (<code object b at 0x7efceaa256f0, file "<ipython-input-1-20ba94fb8214>", line 5>)
6 LOAD_CONST 2 ('a.<locals>.b')
8 MAKE_FUNCTION 8
10 STORE_FAST 0 (b)
10 12 LOAD_FAST 0 (b)
14 CALL_FUNCTION 0
16 POP_TOP
18 LOAD_CONST 0 (None)
20 RETURN_VALUE
因此,让我们看一下如何LOAD_CLOSURE
处理ceval.c
。
TARGET(LOAD_CLOSURE) {
PyObject *cell = freevars[oparg];
Py_INCREF(cell);
PUSH(cell);
DISPATCH();
}
因此,我们看到它必须x
从freevars
封闭的范围中查找。
执行模型文档中提到了这一点,其中说:
nonlocal语句使对应的名称引用最近的封闭函数范围中的先前绑定的变量。如果给定名称在任何封闭函数范围中不存在,则 在编译时
引发SyntaxError 。
主要内容:局部变量,全局变量,局部变量和全局变量的综合示例在《 C语言形参和实参的区别》中提到,形参变量要等到函数被调用时才分配内存,调用结束后立即释放内存。这说明形参变量的作用域非常有限,只能在函数内部使用,离开该函数就无效了。 所谓 作用域( Scope ) ,就是变量的有效范围。 不仅对于形参变量,C语言中所有的变量都有自己的作用域。决定变量作用域的是变量的定义位置。 局部变量 定义在函数内部的变量称为 局部变量(Local Variable) ,
Lua 的设计有一点很奇怪,在一个 block 中的变量,如果之前没有定义过,那么认为它是一个全局变量,而不是这个 block 的局部变量。这一点和别的语言不同。容易造成不小心覆盖了全局同名变量的错误。 定义 Lua 中的局部变量要用 local 关键字来显式定义,不使用 local 显式定义的变量就是全局变量: g_var = 1 -- global var local l_va
简介 在前面的章节中,我已经讲述了如何定义函数。在本节中,我讲介绍局部变量,这将会使定义函数变得更加容易。 let表达式 使用let表达式可以定义局部变量。格式如下: (let binds body) 变量在binds定义的形式中被声明并初始化。body由任意多个S-表达式构成。binds的格式如下: [binds] → ((p1 v1) (p2 v2) ...) 声明了变量p1、p2,并分别
局部变量用于模版渲染,也就是模版中的 site 变量。 默认变量 变量 描述 posts 所有文章 pages 所有分页 categories 所有分类 tags 所有标签 获取变量 hexo.locals.get('posts') 设置变量 hexo.locals.set('posts', function(){ return ... }); 移除变量 hexo.locals.remove(
问题内容: 我了解Python中局部变量和全局变量的概念,但是我只是有一个问题,为什么下面的代码中会出现错误?Python逐行执行代码,因此在读取第5行之前,它不知道a是局部变量。Python尝试执行第5行后,会回退一行并将其标记为错误吗? 问题答案: 设置和测试 为了分析您的问题,让我们创建两个独立的测试函数来复制您的问题: 版画。因此,调用此函数不是问题,而是在下一个函数上: 我们收到一个错误
问题内容: 我还是Python的新手,我一直在尝试提高Python脚本的性能,因此我在有或没有全局变量的情况下对其进行了测试。我给它计时,令我惊讶的是,它在声明了全局变量的情况下运行得更快,而不是将局部变量传递给函数。这是怎么回事?我以为局部变量的执行速度更快?(我知道全球人并不安全,我仍然很好奇。) 问题答案: 当地人应该更快 根据此页面上的本地人和全球人: 当一行代码要求输入变量x的值时,Py