Python变量作用域是如何工作的?
这让我想更深入地挖掘Python源代码,但因为有很多人已经这样做了,我想听听他们的建议Python变量作用域是如何工作的?,python,parsing,scope,grammar,Python,Parsing,Scope,Grammar,这让我想更深入地挖掘Python源代码,但因为有很多人已经这样做了,我想听听他们的建议 >>> import os >>> def scope(): ... print os ... import os ... >>> scope() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<
>>> import os
>>> def scope():
... print os
... import os
...
>>> scope()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in scope
UnboundLocalError: local variable 'os' referenced before assignment
导入操作系统
>>>定义范围():
... 打印操作系统
... 导入操作系统
...
>>>范围()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第2行,在作用域中
UnboundLocalError:分配前引用的局部变量“os”
在我看来,当解析器解释文件时,它会自动为作用域函数创建本地作用域,这使得操作系统与全局作用域“分离”
这是真的吗?有人愿意告诉我在哪里可以找到更多关于范围实现的信息吗
编辑:另外,这不是导入的特例,它也适用于普通变量。当您调用scope()
Python时,会看到您的方法中使用了一个名为os
的局部变量(来自导入内内内内内),因此这会屏蔽全局操作系统。但是,当您说print os
时,您还没有到达该行并执行本地导入,因此您会看到关于赋值前引用的错误。以下是一些可能有帮助的其他示例:
>>> x = 3
>>> def printx():
... print x # will print the global x
...
>>> def printx2():
... print x # will try to print the local x
... x = 4
...
>>> printx()
3
>>> printx2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in printx2
UnboundLocalError: local variable 'x' referenced before assignment
最后,比较这两个示例:
>>> def example1():
... print never_used # will be interpreted as a global
...
>>> def example2():
... print used_later # will be interpreted as the local assigned later
... used_later = 42
...
>>> example1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in example1
NameError: global name 'never_used' is not defined
>>> example2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in example2
UnboundLocalError: local variable 'used_later' referenced before assignment
>>def example1():
... 从未使用过的打印将被解释为全局打印
...
>>>def example2():
... 以后使用的打印将被解释为以后指定的本地打印
... 以后使用=42
...
>>>例1()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第2行,在示例1中
NameError:未定义全局名称“从未使用”
>>>例2()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第2行,在示例2中
UnboundLocalError:赋值前引用的局部变量“used\u later”
函数中变量的任何绑定都会使该变量成为该函数的局部变量<代码>导入
、定义
和类
在这方面都等同于分配
因此,是的,当编译器编译您的文件时,它会创建一个局部变量os
,其作用域与全局os
分开
有关更多信息,请参见Python教程。尤其是第9.2节,词法范围界定是一个常见的问题,大多数设计良好的语言,无论是解释的还是编译的,都使用它
我已经有一段时间没有尝试过了,但请注意漂亮的“global”关键字及其用法如下:
o = 1
def foo():
global o
o = 2
foo()
print o
如果没有“全局”行,对o的修改将本地化,“打印o”将打印1。包括“全局o”行后,它将打印2。我们这样称呼我的函数(没有全局o)将有它自己的变量。上面的全局事件是一种专门请求正常词法范围异常的方法
真正的词法范围界定是Python 1.0所缺乏的,也是Python长期以来所缺乏的(如果我没记错的话,至少从1.6开始)。只有两个作用域,本地和全局,任何中间作用域都是不可访问的。谢谢-但是有关于内部实现的参考资料吗?我想看看解析器是如何工作的。Python是否为每个作用域创建dictionary/struct,并且仅在内部作用域中没有任何内容时才查找外部作用域?我只是想澄清一下我的想法。这不是解析器的问题,而是运行时“查找名称匹配x的最近范围”的问题。
o = 1
def foo():
global o
o = 2
foo()
print o