What exactly are the Python scoping rules?
Python的范围规则到底是什么?
If I have some code:
如果我有一些代码:
code1
class Foo:
code2
def spam.....
code3
for code4..:
code5
x()
Where is x found? Some possible choices include the list above:
x发现在哪里?一些可能的选择包括上面的列表:
- In the enclosing source file
- 在所附的源文件中
- In the class namespace
- 类的命名空间
- In the function definition
- 在函数定义中
- In the for loop index variable
- 在for循环索引变量中
- Inside the for loop
- 在for循环
Also there is the context during execution, when the function spam is passed somewhere else. And maybe lambda functions pass a bit differently?
在执行过程中也有上下文,当函数垃圾邮件传递到其他地方时。也许函数传递的方式有点不同?
There must be a simple reference or algorithm somewhere. It's a confusing world for intermediate Python programmers.
一定有一个简单的引用或算法。对于中级Python程序员来说,这是一个令人困惑的世界。
7 个解决方案
#1
345
Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply)
实际上,从学习Python开始,Python范围解析的一个简明规则,第3。Ed . .(这些规则只针对变量名,而不是属性。如果你引用它没有一个周期,这些规则适用)
LEGB Rule.
LEGB规则。
L, Local — Names assigned in any way within a function (def
or lambda
)), and not declared global in that function.
L, Local——在函数(def或lambda)中以任何方式分配的名称,在该函数中未声明全局。
E, Enclosing-function locals — Name in the local scope of any and all statically enclosing functions (def
or lambda
), from inner to outer.
E,封装函数局部变量——任何或所有静态封闭函数(def或lambda)的局部变量的名称,从内部到外部。
G, Global (module) — Names assigned at the top-level of a module file, or by executing a global
statement in a def
within the file.
全局(模块)——在模块文件的顶层分配的名称,或者在文件中的def中执行全局语句。
B, Built-in (Python) — Names preassigned in the built-in names module : open
,range
,SyntaxError
,...
B,内置(Python) -在内置名称模块中预先分配的名称:open,range,SyntaxError,…
So, in the case of
所以,在
code1
class Foo:
code2
def spam.....
code3
for code4..:
code5
x()
The for loop does not have its own namespace. In LEGB order, the scopes would be
for循环没有自己的命名空间。在LEGB命令中,作用域是。
L : local, in def spam
(in code3
, code 4
, code5
).
L:本地,def spam(在code3, code 4, code5)中。
E : Enclosed function, any enclosing functions (if the whole example were in another def
)
E:封闭函数,任何封闭函数(如果整个例子在另一个def中)
G : Global. Were there any x
declared globally in the module (code1
)?
G:全球。模块中是否有全局声明的x (code1)?
B : Any builtin x
in Python.
B: Python语言中的任何内置x。
x
will never be found in code2
(even in cases where you might expect it would, see Antti's answer or here).
在code2中永远找不到x(即使在您可能认为会找到的情况下,参见Antti的答案或这里)。
#2
134
Essentially, the only thing in Python that introduces a new scope is a function definition. Classes are a bit of a special case in that anything defined directly in the body is placed in the class's namespace, but they are not directly accessible from within the methods (or nested classes) they contain.
本质上,Python中唯一引入新范围的是函数定义。类是一种特殊情况,因为任何直接在主体中定义的内容都放在类的名称空间中,但是它们不能直接从它们包含的方法(或嵌套类)中访问。
In your example there are only 3 scopes where x will be searched in:
在您的示例中,只有3个作用域可以搜索x:
-
spam's scope - containing everything defined in code3 and code5 (as well as code4, your loop variable)
spam范围——包含code3和code5中定义的所有内容(以及code4,您的循环变量)
-
The global scope - containing everything defined in code1, as well as Foo (and whatever changes after it)
全局范围——包含code1中定义的所有内容以及Foo(以及后面的任何更改)
-
The builtins namespace. A bit of a special case - this contains the various Python builtin functions and types such as len() and str(). Generally this shouldn't be modified by any user code, so expect it to contain the standard functions and nothing else.
内置命令名称空间。这是一种特殊情况——它包含各种Python内置函数和类型,如len()和str()。一般来说,任何用户代码都不应该修改它,因此,它应该包含标准函数,而不是其他任何东西。
More scopes only appear when you introduce a nested function (or lambda) into the picture. These will behave pretty much as you'd expect however. The nested function can access everything in the local scope, as well as anything in the enclosing function's scope. eg.
只有在向图中引入嵌套函数(或lambda)时才会出现更多的作用域。不过,它们的表现与您预期的差不多。嵌套函数可以访问本地范围内的所有内容,以及封闭函数范围内的任何内容。如。
def foo():
x=4
def bar():
print x # Accesses x from foo's scope
bar() # Prints 4
x=5
bar() # Prints 5
Restrictions:
限制:
Variables in scopes other than the local function's variables can be accessed, but can't be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope. For example:
除了局部函数的变量之外,作用域中的变量可以被访问,但是如果没有进一步的语法,就不能恢复到新的参数。相反,赋值将创建一个新的局部变量,而不是影响父范围中的变量。例如:
global_var1 = []
global_var2 = 1
def func():
# This is OK: It's just accessing, not rebinding
global_var1.append(4)
# This won't affect global_var2. Instead it creates a new variable
global_var2 = 2
local1 = 4
def embedded_func():
# Again, this doen't affect func's local1 variable. It creates a
# new local variable also called local1 instead.
local1 = 5
print local1
embedded_func() # Prints 5
print local1 # Prints 4
In order to actually modify the bindings of global variables from within a function scope, you need to specify that the variable is global with the global keyword. Eg:
为了实际地从函数范围内修改全局变量的绑定,您需要指定变量是全局变量和全局关键字。例如:
global_var = 4
def change_global():
global global_var
global_var = global_var + 1
Currently there is no way to do the same for variables in enclosing function scopes, but Python 3 introduces a new keyword, "nonlocal
" which will act in a similar way to global, but for nested function scopes.
目前,在封闭函数作用域的变量中没有相同的方法,但是Python 3引入了一个新的关键字“非本地”,它的作用方式与全局作用域类似,但是对于嵌套函数作用域。
#3
81
There was no thorough answer concerning Python3 time, so I made an answer here.
关于毕达哥拉斯的时间没有一个彻底的答案,所以我在这里做了一个回答。
As provided in other answers, there are 4 basic scopes, the LEGB, for Local, Enclosing, Global and Builtin. In addition to those, there is a special scope, the class body, which does not comprise an enclosing scope for methods defined within the class; any assignments within the class body make the variable from there on be bound in the class body.
如其他答案所述,有4个基本范围,即LEGB,用于本地、封闭、全局和内置。除此之外,还有一个特殊的范围,即类主体,它不包含类中定义的方法的封闭范围;课程主体内的任何作业都将变量从那里绑定到课程主体中。
Especially, no block statement, besides def
and class
, create a variable scope. In Python 2 the list comprehension does not create a variable scope, however in Python 3 the loop variable is created in a new scope.
特别是,除了def和class之外,没有任何块语句创建一个变量范围。在Python 2中,列表理解不会创建一个变量范围,但是在Python 3中,循环变量是在一个新的范围中创建的。
To demonstrate the peculiarities of the class body
展示类体的特性
x = 0
class X(object):
y = x
x = x + 1 # x is now a variable
z = x
def method(self):
print(self.x) # -> 1
print(x) # -> 0, the global x
print(y) # -> NameError: global name 'y' is not defined
inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)
Thus unlike in function body, you can reassign the variable to the same name in class body, to get a class variable with the same name; further lookups on this name resolve to the class variable instead.
因此,与函数体不同,您可以将变量重新分配到类主体中相同的名称,以获得具有相同名称的类变量;对这个名称的进一步查找将解析为类变量。
One of the greater surprises to many newcomers to Python is that a for
loop does not create a variable scope. In Python 2 the list comprehensions do not create a scope either (while generators and dict comprehensions do!) Instead they leak the value in the function or the global scope:
对于许多Python新手来说,一个更大的惊喜是for循环不会创建一个变量范围。在Python 2中,列表理解也不创建范围(而生成器和字典理解则创建范围!)相反,它们在函数或全局范围中泄漏值:
>>> [ i for i in range(5) ]
>>> i
4
The comprehensions can be used as a cunning (or awful if you will) way to make modifiable variables within lambda expressions in Python 2 - a lambda expression does create a variable scope, like the def
statement would, but within lambda no statements are allowed. Assignment being a statement in Python means that no variable assignments in lambda are allowed, but a list comprehension is an expression...
这种理解可以作为一种巧妙的(或者如果您愿意的话)方法,在Python 2中的lambda表达式中创建可修改的变量——lambda表达式确实创建了一个变量范围,就像def语句那样,但在lambda表达式中不允许有任何语句。赋值是Python中的语句,意味着在lambda中没有变量赋值,但是列表理解是一个表达式…
This behaviour has been fixed in Python 3 - no comprehension expressions or generators leak variables.
这种行为在Python 3中得到了修正——没有理解表达式或生成器泄漏变量。
The global really means the module scope; the main python module is the __main__
; all imported modules are accessible through the sys.modules
variable; to get access to __main__
one can use sys.modules['__main__']
, or import __main__
; it is perfectly acceptable to access and assign attributes there; they will show up as variables in the global scope of the main module.
全局真的是指模块范围;主要的python模块是__main__;所有导入的模块都可以通过sys进行访问。模块变量;要获得访问权限,可以使用sys。模块(“__main__”),或进口的__main__;在那里访问和分配属性是完全可以接受的;它们将作为变量显示在主模块的全局范围中。
If a name is ever assigned to in the current scope (except in the class scope), it will be considered belonging to that scope, otherwise it will be considered to belonging to any enclosing scope that assigns to the variable (it might not be assigned yet, or not at all), or finally the global scope. If the variable is considered local, but it is not set yet, or has been deleted, reading the variable value will result in UnboundLocalError
, which is a subclass of NameError
.
如果一个名字是分配给在当前范围(在类范围除外),它将被认为是属于范围,否则会被认为属于任何封闭范围分配给变量(这可能未被分配,或不是),或最后全球范围。如果变量被认为是局部的,但是还没有设置,或者已经被删除,那么读取变量值将导致UnboundLocalError,这是NameError的一个子类。
x = 5
def foobar():
print(x) # causes UnboundLocalError!
x += 1 # because assignment here makes x a local variable within the function
# call the function
foobar()
The scope can declare that it explicitly wants to modify the global (module scope) variable, with the global keyword:
作用域可以声明它明确想要修改全局(模块作用域)变量,使用全局关键字:
x = 5
def foobar():
global x
print(x) # -> 5
x += 1
foobar()
print(x) # -> 6
This also is possible even if it was shadowed in enclosing scope:
这也是可能的,即使它被隐藏在封闭范围内:
x = 5
y = 13
def make_closure():
x = 42
y = 911
def func():
global x # sees the global value
print(x, y)
x += 1
return func
func = make_closure()
func() # -> print 5 911
print(x, y) # -> 6 13
In python 2 there is no easy way to modify the value in the enclosing scope; usually this is simulated by having a mutable value, such as a list with length of 1:
在python 2中,没有简单的方法可以在封闭范围内修改值;通常这是通过一个可变值来模拟的,比如一个长度为1的列表:
def make_closure():
value = [0]
def get_next_value():
value[0] += 1
return value[0]
return get_next_value
get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2
However in python 3, the nonlocal
comes to rescue:
然而在《蟒蛇》3中,非本地的人来拯救:
def make_closure():
value = 0
def get_next_value():
nonlocal value
value += 1
return value
return get_next_value
get_next = make_closure() # identical behavior to the previous example.
Any variable that is not deemed to be local to the current scope, or any enclosing scope, is a global variable. A global name is looked up in the module global dictionary; if not found, the global is then looked up from the builtins module; the name of the module was changed from python 2 to python 3; in python 2 it was __builtin__
and in python 3 it is now called builtins
. If you assign to an attribute of builtins module, it will be visible thereafter to any module as a readable global variable, unless that module shadows them with its own global variable with the same name.
任何不被认为是当前范围的局部变量或任何封闭范围的变量都是全局变量。在模块全局字典中查找全局名称;如果没有找到,则从builtins模块查找全局变量;模块名称由python 2改为python 3;在python 2中,它是__builtin__,在python 3中,它现在被称为builtins。如果您为builtins模块的属性赋值,那么它将作为可读的全局变量在以后的任何模块中都是可见的,除非该模块用相同名称的全局变量阴影它们。
Reading the builtin module can also be useful; suppose that you want the python 3 style print function in some parts of file, but other parts of file still use the print
statement, if your python version is >= 2.6, you can get the new style function as:
读取内置模块也很有用;假设您希望在文件的某些部分使用python 3风格的打印函数,但文件的其他部分仍然使用print语句,如果您的python版本是>= 2.6,则可以得到新的样式函数为:
import __builtin__
print3 = __builtin__.__dict__['print']
The from __future__ import print_function
actually does not import the print
function anywhere in Python 2 - instead it just disables the parsing rules for print
statement in the current module, handling print
like any other variable identifier, and thus allowing the print
the function be looked up in the builtins.
from __future__进口print_function实际上并不导入打印函数在Python 2 -它只是禁用打印语句的解析规则在当前模块,处理打印像任何其他变量标识符,因此允许打印功能是内置抬头。
#4
20
The scoping rules for Python 2.x have been outlined already in other answers. The only thing I would add is that in Python 3.0, there is also the concept of a non-local scope (indicated by the 'nonlocal' keyword). This allows you to access outer scopes directly, and opens up the ability to do some neat tricks, including lexical closures (without ugly hacks involving mutable objects).
Python 2的范围规则。其他答案中已经列出了x。我唯一要补充的是在Python 3.0中,还有一个非本地范围的概念(由“非本地”关键字表示)。这允许您直接访问外部作用域,并允许您进行一些巧妙的操作,包括词汇闭包(不需要涉及可变对象的丑陋操作)。
EDIT: Here's the PEP with more information on this.
编辑:这里是PEP关于此的更多信息。
#5
18
A slightly more complete example of scope:
更完整的范围示例:
from __future__ import print_function # for python 2 support
x = 100
print("1. Global x:", x)
class Test(object):
y = x
print("2. Enclosed y:", y)
x = x + 1
print("3. Enclosed x:", x)
def method(self):
print("4. Enclosed self.x", self.x)
print("5. Global x", x)
try:
print(y)
except NameError as e:
print("6.", e)
def method_local_ref(self):
try:
print(x)
except UnboundLocalError as e:
print("7.", e)
x = 200 # causing 7 because has same name
print("8. Local x", x)
inst = Test()
inst.method()
inst.method_local_ref()
output:
输出:
1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. global name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200
#6
10
Python resolves your variables with -- generally -- three namespaces available.
Python通常使用三个可用的名称空间来解析变量。
At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: the innermost scope, which is searched first, contains the local names; the namespaces of any enclosing functions, which are searched starting with the nearest enclosing scope; the middle scope, searched next, contains the current module's global names; and the outermost scope (searched last) is the namespace containing built-in names.
在执行期间的任何时候,至少有三个嵌套的作用域,它们的名称空间是可以直接访问的:最内部的作用域(首先进行搜索)包含本地名称;任何封闭函数的名称空间,从最近的封闭范围开始搜索;接下来搜索的中间范围包含当前模块的全局名称;最外层的作用域(最后搜索)是包含内置名称的名称空间。
There are two functions: globals
and locals
which show you the contents two of these namespaces.
有两个函数:全局变量和局部变量,它们向您显示这些名称空间中的两个内容。
Namespaces are created by packages, modules, classes, object construction and functions. There aren't any other flavors of namespaces.
名称空间由包、模块、类、对象构造和函数创建。名称空间没有其他的风格。
In this case, the call to a function named x
has to be resolved in the local name space or the global namespace.
在这种情况下,必须在本地名称空间或全局名称空间中解析对名为x的函数的调用。
Local in this case, is the body of the method function Foo.spam
.
在本例中,Local是方法Foo.spam的主体函数。
Global is -- well -- global.
全球是——嗯——全球。
The rule is to search the nested local spaces created by method functions (and nested function definitions), then search global. That's it.
规则是搜索由方法函数(和嵌套函数定义)创建的嵌套的本地空间,然后搜索全局。就是这样。
There are no other scopes. The for
statement (and other compound statements like if
and try
) don't create new nested scopes. Only definitions (packages, modules, functions, classes and object instances.)
没有其他作用域。for语句(以及其他复合语句,如if和try)不创建新的嵌套范围。只有定义(包、模块、函数、类和对象实例)。
Inside a class definition, the names are part of the class namespace. code2
, for instance, must be qualified by the class name. Generally Foo.code2
. However, self.code2
will also work because Python objects look at the containing class as a fall-back.
在类定义中,名称是类名称空间的一部分。例如,code2必须符合类名。一般Foo.code2。然而,自我。code2也可以工作,因为Python对象将包含类视为回退。
An object (an instance of a class) has instance variables. These names are in the object's namespace. They must be qualified by the object. (variable.instance
.)
对象(类的实例)具有实例变量。这些名称位于对象的名称空间中。他们必须被这个物体限定。(variable.instance)。
From within a class method, you have locals and globals. You say self.variable
to pick the instance as the namespace. You'll note that self
is an argument to every class member function, making it part of the local namespace.
在类方法中,有局部变量和全局变量。你说的自我。选择实例作为命名空间的变量。您将注意到self是每个类成员函数的参数,使其成为本地名称空间的一部分。
See Python Scope Rules, Python Scope, Variable Scope.
请参阅Python范围规则、Python范围、变量范围。
#7
7
Where is x found?
x发现在哪里?
x is not found as you haven't defined it. :-) It could be found in code1 (global) or code3 (local) if you put it there.
x没有找到,因为你还没有定义它。:-)如果放在那里,可以在code1 (global)或code3 (local)中找到。
code2 (class members) aren't visible to code inside methods of the same class — you would usually access them using self. code4/code5 (loops) live in the same scope as code3, so if you wrote to x in there you would be changing the x instance defined in code3, not making a new x.
在同一个类的方法中,代码2(类成员)是不可见的——您通常使用self访问它们。code4/code5(循环)与code3的作用域相同,因此如果您在其中对x进行写入,您将会更改code3中定义的x实例,而不是创建新的x。
Python is statically scoped, so if you pass ‘spam’ to another function spam will still have access to globals in the module it came from (defined in code1), and any other containing scopes (see below). code2 members would again be accessed through self.
Python的作用域是静态的,所以如果您将“spam”传递给另一个函数,spam仍然可以访问它来自的模块中的全局变量(在code1中定义),以及任何其他包含范围的全局变量(参见下面)。code2成员将再次通过self访问。
lambda is no different to def. If you have a lambda used inside a function, it's the same as defining a nested function. In Python 2.2 onwards, nested scopes are available. In this case you can bind x at any level of function nesting and Python will pick up the innermost instance:
和def没什么区别,如果你在一个函数中使用了一个lambda函数,它和定义一个嵌套函数是一样的。在Python 2.2中,可以使用嵌套的范围。在这种情况下,您可以在函数嵌套的任何级别绑定x, Python将选择最内部的实例:
x= 0
def fun1():
x= 1
def fun2():
x= 2
def fun3():
return x
return fun3()
return fun2()
print fun1(), x
2 0
fun3 sees the instance x from the nearest containing scope, which is the function scope associated with fun2. But the other x instances, defined in fun1 and globally, are not affected.
fun3从最近的包含范围(即与fun2关联的函数范围)看到实例x。但是在fun1和全局定义的其他x实例不受影响。
Before nested_scopes — in Python pre-2.1, and in 2.1 unless you specifically ask for the feature using a from-future-import — fun1 and fun2's scopes are not visible to fun3, so S.Lott's answer holds and you would get the global x:
在nested_scope之前——在Python pre-2.1中,在2.1中,除非您特别要求使用from- futureimport——fun1和fun2的作用域对fun3是不可见的,所以S。洛特的答案是成立的,你会得到全局x:
0 0
#1
345
Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply)
实际上,从学习Python开始,Python范围解析的一个简明规则,第3。Ed . .(这些规则只针对变量名,而不是属性。如果你引用它没有一个周期,这些规则适用)
LEGB Rule.
LEGB规则。
L, Local — Names assigned in any way within a function (def
or lambda
)), and not declared global in that function.
L, Local——在函数(def或lambda)中以任何方式分配的名称,在该函数中未声明全局。
E, Enclosing-function locals — Name in the local scope of any and all statically enclosing functions (def
or lambda
), from inner to outer.
E,封装函数局部变量——任何或所有静态封闭函数(def或lambda)的局部变量的名称,从内部到外部。
G, Global (module) — Names assigned at the top-level of a module file, or by executing a global
statement in a def
within the file.
全局(模块)——在模块文件的顶层分配的名称,或者在文件中的def中执行全局语句。
B, Built-in (Python) — Names preassigned in the built-in names module : open
,range
,SyntaxError
,...
B,内置(Python) -在内置名称模块中预先分配的名称:open,range,SyntaxError,…
So, in the case of
所以,在
code1
class Foo:
code2
def spam.....
code3
for code4..:
code5
x()
The for loop does not have its own namespace. In LEGB order, the scopes would be
for循环没有自己的命名空间。在LEGB命令中,作用域是。
L : local, in def spam
(in code3
, code 4
, code5
).
L:本地,def spam(在code3, code 4, code5)中。
E : Enclosed function, any enclosing functions (if the whole example were in another def
)
E:封闭函数,任何封闭函数(如果整个例子在另一个def中)
G : Global. Were there any x
declared globally in the module (code1
)?
G:全球。模块中是否有全局声明的x (code1)?
B : Any builtin x
in Python.
B: Python语言中的任何内置x。
x
will never be found in code2
(even in cases where you might expect it would, see Antti's answer or here).
在code2中永远找不到x(即使在您可能认为会找到的情况下,参见Antti的答案或这里)。
#2
134
Essentially, the only thing in Python that introduces a new scope is a function definition. Classes are a bit of a special case in that anything defined directly in the body is placed in the class's namespace, but they are not directly accessible from within the methods (or nested classes) they contain.
本质上,Python中唯一引入新范围的是函数定义。类是一种特殊情况,因为任何直接在主体中定义的内容都放在类的名称空间中,但是它们不能直接从它们包含的方法(或嵌套类)中访问。
In your example there are only 3 scopes where x will be searched in:
在您的示例中,只有3个作用域可以搜索x:
-
spam's scope - containing everything defined in code3 and code5 (as well as code4, your loop variable)
spam范围——包含code3和code5中定义的所有内容(以及code4,您的循环变量)
-
The global scope - containing everything defined in code1, as well as Foo (and whatever changes after it)
全局范围——包含code1中定义的所有内容以及Foo(以及后面的任何更改)
-
The builtins namespace. A bit of a special case - this contains the various Python builtin functions and types such as len() and str(). Generally this shouldn't be modified by any user code, so expect it to contain the standard functions and nothing else.
内置命令名称空间。这是一种特殊情况——它包含各种Python内置函数和类型,如len()和str()。一般来说,任何用户代码都不应该修改它,因此,它应该包含标准函数,而不是其他任何东西。
More scopes only appear when you introduce a nested function (or lambda) into the picture. These will behave pretty much as you'd expect however. The nested function can access everything in the local scope, as well as anything in the enclosing function's scope. eg.
只有在向图中引入嵌套函数(或lambda)时才会出现更多的作用域。不过,它们的表现与您预期的差不多。嵌套函数可以访问本地范围内的所有内容,以及封闭函数范围内的任何内容。如。
def foo():
x=4
def bar():
print x # Accesses x from foo's scope
bar() # Prints 4
x=5
bar() # Prints 5
Restrictions:
限制:
Variables in scopes other than the local function's variables can be accessed, but can't be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope. For example:
除了局部函数的变量之外,作用域中的变量可以被访问,但是如果没有进一步的语法,就不能恢复到新的参数。相反,赋值将创建一个新的局部变量,而不是影响父范围中的变量。例如:
global_var1 = []
global_var2 = 1
def func():
# This is OK: It's just accessing, not rebinding
global_var1.append(4)
# This won't affect global_var2. Instead it creates a new variable
global_var2 = 2
local1 = 4
def embedded_func():
# Again, this doen't affect func's local1 variable. It creates a
# new local variable also called local1 instead.
local1 = 5
print local1
embedded_func() # Prints 5
print local1 # Prints 4
In order to actually modify the bindings of global variables from within a function scope, you need to specify that the variable is global with the global keyword. Eg:
为了实际地从函数范围内修改全局变量的绑定,您需要指定变量是全局变量和全局关键字。例如:
global_var = 4
def change_global():
global global_var
global_var = global_var + 1
Currently there is no way to do the same for variables in enclosing function scopes, but Python 3 introduces a new keyword, "nonlocal
" which will act in a similar way to global, but for nested function scopes.
目前,在封闭函数作用域的变量中没有相同的方法,但是Python 3引入了一个新的关键字“非本地”,它的作用方式与全局作用域类似,但是对于嵌套函数作用域。
#3
81
There was no thorough answer concerning Python3 time, so I made an answer here.
关于毕达哥拉斯的时间没有一个彻底的答案,所以我在这里做了一个回答。
As provided in other answers, there are 4 basic scopes, the LEGB, for Local, Enclosing, Global and Builtin. In addition to those, there is a special scope, the class body, which does not comprise an enclosing scope for methods defined within the class; any assignments within the class body make the variable from there on be bound in the class body.
如其他答案所述,有4个基本范围,即LEGB,用于本地、封闭、全局和内置。除此之外,还有一个特殊的范围,即类主体,它不包含类中定义的方法的封闭范围;课程主体内的任何作业都将变量从那里绑定到课程主体中。
Especially, no block statement, besides def
and class
, create a variable scope. In Python 2 the list comprehension does not create a variable scope, however in Python 3 the loop variable is created in a new scope.
特别是,除了def和class之外,没有任何块语句创建一个变量范围。在Python 2中,列表理解不会创建一个变量范围,但是在Python 3中,循环变量是在一个新的范围中创建的。
To demonstrate the peculiarities of the class body
展示类体的特性
x = 0
class X(object):
y = x
x = x + 1 # x is now a variable
z = x
def method(self):
print(self.x) # -> 1
print(x) # -> 0, the global x
print(y) # -> NameError: global name 'y' is not defined
inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)
Thus unlike in function body, you can reassign the variable to the same name in class body, to get a class variable with the same name; further lookups on this name resolve to the class variable instead.
因此,与函数体不同,您可以将变量重新分配到类主体中相同的名称,以获得具有相同名称的类变量;对这个名称的进一步查找将解析为类变量。
One of the greater surprises to many newcomers to Python is that a for
loop does not create a variable scope. In Python 2 the list comprehensions do not create a scope either (while generators and dict comprehensions do!) Instead they leak the value in the function or the global scope:
对于许多Python新手来说,一个更大的惊喜是for循环不会创建一个变量范围。在Python 2中,列表理解也不创建范围(而生成器和字典理解则创建范围!)相反,它们在函数或全局范围中泄漏值:
>>> [ i for i in range(5) ]
>>> i
4
The comprehensions can be used as a cunning (or awful if you will) way to make modifiable variables within lambda expressions in Python 2 - a lambda expression does create a variable scope, like the def
statement would, but within lambda no statements are allowed. Assignment being a statement in Python means that no variable assignments in lambda are allowed, but a list comprehension is an expression...
这种理解可以作为一种巧妙的(或者如果您愿意的话)方法,在Python 2中的lambda表达式中创建可修改的变量——lambda表达式确实创建了一个变量范围,就像def语句那样,但在lambda表达式中不允许有任何语句。赋值是Python中的语句,意味着在lambda中没有变量赋值,但是列表理解是一个表达式…
This behaviour has been fixed in Python 3 - no comprehension expressions or generators leak variables.
这种行为在Python 3中得到了修正——没有理解表达式或生成器泄漏变量。
The global really means the module scope; the main python module is the __main__
; all imported modules are accessible through the sys.modules
variable; to get access to __main__
one can use sys.modules['__main__']
, or import __main__
; it is perfectly acceptable to access and assign attributes there; they will show up as variables in the global scope of the main module.
全局真的是指模块范围;主要的python模块是__main__;所有导入的模块都可以通过sys进行访问。模块变量;要获得访问权限,可以使用sys。模块(“__main__”),或进口的__main__;在那里访问和分配属性是完全可以接受的;它们将作为变量显示在主模块的全局范围中。
If a name is ever assigned to in the current scope (except in the class scope), it will be considered belonging to that scope, otherwise it will be considered to belonging to any enclosing scope that assigns to the variable (it might not be assigned yet, or not at all), or finally the global scope. If the variable is considered local, but it is not set yet, or has been deleted, reading the variable value will result in UnboundLocalError
, which is a subclass of NameError
.
如果一个名字是分配给在当前范围(在类范围除外),它将被认为是属于范围,否则会被认为属于任何封闭范围分配给变量(这可能未被分配,或不是),或最后全球范围。如果变量被认为是局部的,但是还没有设置,或者已经被删除,那么读取变量值将导致UnboundLocalError,这是NameError的一个子类。
x = 5
def foobar():
print(x) # causes UnboundLocalError!
x += 1 # because assignment here makes x a local variable within the function
# call the function
foobar()
The scope can declare that it explicitly wants to modify the global (module scope) variable, with the global keyword:
作用域可以声明它明确想要修改全局(模块作用域)变量,使用全局关键字:
x = 5
def foobar():
global x
print(x) # -> 5
x += 1
foobar()
print(x) # -> 6
This also is possible even if it was shadowed in enclosing scope:
这也是可能的,即使它被隐藏在封闭范围内:
x = 5
y = 13
def make_closure():
x = 42
y = 911
def func():
global x # sees the global value
print(x, y)
x += 1
return func
func = make_closure()
func() # -> print 5 911
print(x, y) # -> 6 13
In python 2 there is no easy way to modify the value in the enclosing scope; usually this is simulated by having a mutable value, such as a list with length of 1:
在python 2中,没有简单的方法可以在封闭范围内修改值;通常这是通过一个可变值来模拟的,比如一个长度为1的列表:
def make_closure():
value = [0]
def get_next_value():
value[0] += 1
return value[0]
return get_next_value
get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2
However in python 3, the nonlocal
comes to rescue:
然而在《蟒蛇》3中,非本地的人来拯救:
def make_closure():
value = 0
def get_next_value():
nonlocal value
value += 1
return value
return get_next_value
get_next = make_closure() # identical behavior to the previous example.
Any variable that is not deemed to be local to the current scope, or any enclosing scope, is a global variable. A global name is looked up in the module global dictionary; if not found, the global is then looked up from the builtins module; the name of the module was changed from python 2 to python 3; in python 2 it was __builtin__
and in python 3 it is now called builtins
. If you assign to an attribute of builtins module, it will be visible thereafter to any module as a readable global variable, unless that module shadows them with its own global variable with the same name.
任何不被认为是当前范围的局部变量或任何封闭范围的变量都是全局变量。在模块全局字典中查找全局名称;如果没有找到,则从builtins模块查找全局变量;模块名称由python 2改为python 3;在python 2中,它是__builtin__,在python 3中,它现在被称为builtins。如果您为builtins模块的属性赋值,那么它将作为可读的全局变量在以后的任何模块中都是可见的,除非该模块用相同名称的全局变量阴影它们。
Reading the builtin module can also be useful; suppose that you want the python 3 style print function in some parts of file, but other parts of file still use the print
statement, if your python version is >= 2.6, you can get the new style function as:
读取内置模块也很有用;假设您希望在文件的某些部分使用python 3风格的打印函数,但文件的其他部分仍然使用print语句,如果您的python版本是>= 2.6,则可以得到新的样式函数为:
import __builtin__
print3 = __builtin__.__dict__['print']
The from __future__ import print_function
actually does not import the print
function anywhere in Python 2 - instead it just disables the parsing rules for print
statement in the current module, handling print
like any other variable identifier, and thus allowing the print
the function be looked up in the builtins.
from __future__进口print_function实际上并不导入打印函数在Python 2 -它只是禁用打印语句的解析规则在当前模块,处理打印像任何其他变量标识符,因此允许打印功能是内置抬头。
#4
20
The scoping rules for Python 2.x have been outlined already in other answers. The only thing I would add is that in Python 3.0, there is also the concept of a non-local scope (indicated by the 'nonlocal' keyword). This allows you to access outer scopes directly, and opens up the ability to do some neat tricks, including lexical closures (without ugly hacks involving mutable objects).
Python 2的范围规则。其他答案中已经列出了x。我唯一要补充的是在Python 3.0中,还有一个非本地范围的概念(由“非本地”关键字表示)。这允许您直接访问外部作用域,并允许您进行一些巧妙的操作,包括词汇闭包(不需要涉及可变对象的丑陋操作)。
EDIT: Here's the PEP with more information on this.
编辑:这里是PEP关于此的更多信息。
#5
18
A slightly more complete example of scope:
更完整的范围示例:
from __future__ import print_function # for python 2 support
x = 100
print("1. Global x:", x)
class Test(object):
y = x
print("2. Enclosed y:", y)
x = x + 1
print("3. Enclosed x:", x)
def method(self):
print("4. Enclosed self.x", self.x)
print("5. Global x", x)
try:
print(y)
except NameError as e:
print("6.", e)
def method_local_ref(self):
try:
print(x)
except UnboundLocalError as e:
print("7.", e)
x = 200 # causing 7 because has same name
print("8. Local x", x)
inst = Test()
inst.method()
inst.method_local_ref()
output:
输出:
1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. global name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200
#6
10
Python resolves your variables with -- generally -- three namespaces available.
Python通常使用三个可用的名称空间来解析变量。
At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: the innermost scope, which is searched first, contains the local names; the namespaces of any enclosing functions, which are searched starting with the nearest enclosing scope; the middle scope, searched next, contains the current module's global names; and the outermost scope (searched last) is the namespace containing built-in names.
在执行期间的任何时候,至少有三个嵌套的作用域,它们的名称空间是可以直接访问的:最内部的作用域(首先进行搜索)包含本地名称;任何封闭函数的名称空间,从最近的封闭范围开始搜索;接下来搜索的中间范围包含当前模块的全局名称;最外层的作用域(最后搜索)是包含内置名称的名称空间。
There are two functions: globals
and locals
which show you the contents two of these namespaces.
有两个函数:全局变量和局部变量,它们向您显示这些名称空间中的两个内容。
Namespaces are created by packages, modules, classes, object construction and functions. There aren't any other flavors of namespaces.
名称空间由包、模块、类、对象构造和函数创建。名称空间没有其他的风格。
In this case, the call to a function named x
has to be resolved in the local name space or the global namespace.
在这种情况下,必须在本地名称空间或全局名称空间中解析对名为x的函数的调用。
Local in this case, is the body of the method function Foo.spam
.
在本例中,Local是方法Foo.spam的主体函数。
Global is -- well -- global.
全球是——嗯——全球。
The rule is to search the nested local spaces created by method functions (and nested function definitions), then search global. That's it.
规则是搜索由方法函数(和嵌套函数定义)创建的嵌套的本地空间,然后搜索全局。就是这样。
There are no other scopes. The for
statement (and other compound statements like if
and try
) don't create new nested scopes. Only definitions (packages, modules, functions, classes and object instances.)
没有其他作用域。for语句(以及其他复合语句,如if和try)不创建新的嵌套范围。只有定义(包、模块、函数、类和对象实例)。
Inside a class definition, the names are part of the class namespace. code2
, for instance, must be qualified by the class name. Generally Foo.code2
. However, self.code2
will also work because Python objects look at the containing class as a fall-back.
在类定义中,名称是类名称空间的一部分。例如,code2必须符合类名。一般Foo.code2。然而,自我。code2也可以工作,因为Python对象将包含类视为回退。
An object (an instance of a class) has instance variables. These names are in the object's namespace. They must be qualified by the object. (variable.instance
.)
对象(类的实例)具有实例变量。这些名称位于对象的名称空间中。他们必须被这个物体限定。(variable.instance)。
From within a class method, you have locals and globals. You say self.variable
to pick the instance as the namespace. You'll note that self
is an argument to every class member function, making it part of the local namespace.
在类方法中,有局部变量和全局变量。你说的自我。选择实例作为命名空间的变量。您将注意到self是每个类成员函数的参数,使其成为本地名称空间的一部分。
See Python Scope Rules, Python Scope, Variable Scope.
请参阅Python范围规则、Python范围、变量范围。
#7
7
Where is x found?
x发现在哪里?
x is not found as you haven't defined it. :-) It could be found in code1 (global) or code3 (local) if you put it there.
x没有找到,因为你还没有定义它。:-)如果放在那里,可以在code1 (global)或code3 (local)中找到。
code2 (class members) aren't visible to code inside methods of the same class — you would usually access them using self. code4/code5 (loops) live in the same scope as code3, so if you wrote to x in there you would be changing the x instance defined in code3, not making a new x.
在同一个类的方法中,代码2(类成员)是不可见的——您通常使用self访问它们。code4/code5(循环)与code3的作用域相同,因此如果您在其中对x进行写入,您将会更改code3中定义的x实例,而不是创建新的x。
Python is statically scoped, so if you pass ‘spam’ to another function spam will still have access to globals in the module it came from (defined in code1), and any other containing scopes (see below). code2 members would again be accessed through self.
Python的作用域是静态的,所以如果您将“spam”传递给另一个函数,spam仍然可以访问它来自的模块中的全局变量(在code1中定义),以及任何其他包含范围的全局变量(参见下面)。code2成员将再次通过self访问。
lambda is no different to def. If you have a lambda used inside a function, it's the same as defining a nested function. In Python 2.2 onwards, nested scopes are available. In this case you can bind x at any level of function nesting and Python will pick up the innermost instance:
和def没什么区别,如果你在一个函数中使用了一个lambda函数,它和定义一个嵌套函数是一样的。在Python 2.2中,可以使用嵌套的范围。在这种情况下,您可以在函数嵌套的任何级别绑定x, Python将选择最内部的实例:
x= 0
def fun1():
x= 1
def fun2():
x= 2
def fun3():
return x
return fun3()
return fun2()
print fun1(), x
2 0
fun3 sees the instance x from the nearest containing scope, which is the function scope associated with fun2. But the other x instances, defined in fun1 and globally, are not affected.
fun3从最近的包含范围(即与fun2关联的函数范围)看到实例x。但是在fun1和全局定义的其他x实例不受影响。
Before nested_scopes — in Python pre-2.1, and in 2.1 unless you specifically ask for the feature using a from-future-import — fun1 and fun2's scopes are not visible to fun3, so S.Lott's answer holds and you would get the global x:
在nested_scope之前——在Python pre-2.1中,在2.1中,除非您特别要求使用from- futureimport——fun1和fun2的作用域对fun3是不可见的,所以S。洛特的答案是成立的,你会得到全局x:
0 0