Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python变量作用域是如何工作的?_Python_Parsing_Scope_Grammar - Fatal编程技术网

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 "<

这让我想更深入地挖掘Python源代码,但因为有很多人已经这样做了,我想听听他们的建议

>>> 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