在Python常见问题中,我们可以读到:
在Python中,仅在函数中引用的变量是隐式全局的。
从关于定义函数的Python教程,我们可以读到:
函数的执行引入了一个新的符号表,用于函数的局部变量。更准确地说,函数中的所有变量赋值都将值存储在本地符号表中;而变量引用则首先在本地符号表中查找,然后在封闭函数的本地符号表中,然后在全局符号表中,最后在内置名称表中。
现在,我完全理解了教程中的语句,但接着说,variables that are only referenced inside a function are implicitly global对我来说似乎相当模糊。
如果我们实际上开始查看本地符号表,然后使用更“通用”的表,那么为什么说它们是隐含的全局的呢?这仅仅是一种说法吗?如果您只想在函数中引用一个变量,那么您不需要担心它是本地变量还是global变量
发布于 2014-05-04 16:54:33
示例
(有关摘要,请参阅下文)
这意味着,如果--如果变量是--在函数体中从未分配给,那么它将被视为全局变量。
这就解释了为什么以下工作(a被视为全局的):
a = 1
def fn():
print a # This is "referencing a variable" == "reading its value"
# Prints: 1但是,如果变量被分配到函数的body中的某个位置,那么它将被视为整个函数体的本地。
这包括在分配给它之前找到的语句(参见下面的示例)。
这就解释了为什么下面的不工作。在这里,a被视为本地的,
a = 1
def fn():
print a
a = 2 # <<< We're adding this
fn()
# Throws: UnboundLocalError: local variable 'a' referenced before assignment您可以让Python使用global a语句将变量视为全局变量。如果这样做,那么变量将再次被视为全局的,,对于整个函数体。
a = 1
def fn():
global a # <<< We're adding this
print a
a = 2
fn()
print a
# Prints: 1
# Then, prints: 2 (a changed in the global scope too)摘要
与您可能预期的不同,如果无法在本地作用域中找到,Python将不会返回到全局范围。
这意味着变量是整个函数体的本地或全局:它不能是全局的,然后变成本地的。
现在,关于变量是本地的还是全局的,Python遵循以下规则。变量是:
global语句,则为全局global )进一步说明
事实上,“隐式全球化”并不意味着全球性。下面是一个更好的思考方法:
因此,如果一个变量是“隐式全局的”(==“在函数之外”),那么将首先查找它的“封闭作用域”:
a = 25
def enclosing():
a = 2
def enclosed():
print a
enclosed()
enclosing()
# Prints 2, as supplied in the enclosing scope, instead of 25 (found in the global scope)现在,和往常一样,global允许您引用全局范围。
a = 25
def enclosing():
a = 2
def enclosed():
global a # <<< We're adding this
print a
enclosed()
enclosing()
# Prints 25, as supplied in the global scope现在,如果您需要在a中指定enclosed,并且希望在enclosing的作用域中而不是在全局范围内更改a的值,那么您将需要nonlocal,这在Python3中是新的。在Python2中,您不能。
发布于 2014-05-04 16:54:44
Python的名称解析方案有时被称为LEGB规则,以范围名称之后的名称命名.
当在函数中使用非限定名时,Python最多搜索四个作用域--本地(L)作用域,然后搜索包含(E) defs和lambdas的本地作用域,然后搜索全局(G)作用域,然后搜索内置(B)作用域,并在找到名称的第一处停止。如果在此搜索过程中找不到名称,Python将报告一个错误。
换句话说,默认情况下,函数def语句(或lambda)中分配的所有名称都是局部变量。函数可以自由地使用在语法上包围函数和全局范围中分配的名称,但是它们必须声明这样的nonlocals和globals才能更改它们。
参考资料:http://goo.gl/woLW0F
发布于 2014-05-04 16:55:07
这是令人困惑的,而且文档可能会更加清晰。
此上下文中的“所引用”意味着名称不是分配给的,而是简单地从。例如,当a = 1分配给a时,print(a) (Python3语法)引用的是没有任何赋值的a。
如果您像上面一样引用a而没有任何赋值,那么Python解释器会递归地搜索当前名称空间的父名称空间,直到它到达全局命名空间为止。
另一方面,如果将变量赋值给一个变量,则该变量仅在本地命名空间中定义,除非使用global关键字另作声明。因此,a = 1在本地命名空间中创建了一个新名称a。在更高的命名空间中,这优先于任何其他名为a的变量。
https://stackoverflow.com/questions/23458854
复制相似问题