Python 范围界定规则的简短描述?
Python的作用域规则是什么 如果我有一些代码:Python 范围界定规则的简短描述?,python,scope,dynamic-languages,Python,Scope,Dynamic Languages,Python的作用域规则是什么 如果我有一些代码: code1 class Foo: code2 def spam..... code3 for code4..: code5 x() 在哪里可以找到x?一些可能的选择包括以下列表: 在封闭的源文件中 在类命名空间中 在函数定义中 for循环中的索引变量 在for循环内部 当函数spam被传递到其他地方时,执行过程中还存在上下文。也许通过的方式会有所不同 一定有一个简单的参考或算法。
code1
class Foo:
code2
def spam.....
code3
for code4..:
code5
x()
在哪里可以找到x
?一些可能的选择包括以下列表:
spam
被传递到其他地方时,执行过程中还存在上下文。也许通过的方式会有所不同
一定有一个简单的参考或算法。对于中级Python程序员来说,这是一个令人困惑的世界。Python通常使用三个可用的名称空间来解析变量 在执行过程中的任何时候 至少有三个嵌套作用域 名称空间可以直接访问: 最内部的作用域,将对其进行搜索 首先,包含本地名称;这个 任何封闭函数的名称空间, 从 最近封闭范围;中间 下一步搜索的范围包含 当前模块的全局名称;和 最外层的范围(最后搜索)是 包含内置名称的命名空间 有两个函数:
globals
和locals
向您显示这两个名称空间的内容
名称空间由包、模块、类、对象构造和函数创建。没有任何其他风格的名称空间
在这种情况下,对名为x
的函数的调用必须在本地名称空间或全局名称空间中解析
在本例中,Local是方法函数Foo.spam
的主体
全球是——嗯——全球的
规则是搜索由方法函数(和嵌套函数定义)创建的嵌套局部空间,然后搜索全局空间。就这样
没有其他作用域。for
语句(以及其他复合语句,如if
和try
)不会创建新的嵌套作用域。仅定义(包、模块、函数、类和对象实例)
在类定义中,名称是类命名空间的一部分<例如,code>code2,必须由类名限定。通常Foo.code2
。但是,self.code2
也可以工作,因为Python对象将包含的类视为一个后备类
对象(类的实例)具有实例变量。这些名称位于对象的命名空间中。它们必须由对象限定。(variable.instance
)
在类方法中,有局部变量和全局变量。您可以说self.variable
来选择实例作为名称空间。您将注意到,self
是每个类成员函数的参数,使其成为本地名称空间的一部分
见
x在哪里
找不到x,因为您尚未定义它。:-)如果你把它放在那里,可以在代码1(全局)或代码3(本地)中找到它
代码2(类成员)对同一类的方法内部的代码不可见 — 您通常会使用self访问它们。code4/code5(循环)与code3在同一范围内,因此如果您在其中写入x,您将更改code3中定义的x实例,而不是生成新的x
Python的作用域是静态的,因此如果您将“spam”传递给另一个函数,spam仍然可以访问它来自的模块(在code1中定义)中的全局变量,以及任何其他包含作用域的函数(见下文)。代码2成员将再次通过self访问
lambda与def没有什么不同。如果在函数中使用lambda,则与定义嵌套函数相同。在Python2.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从最近的包含范围(与fun2关联的函数范围)查看实例x。但fun1中定义的其他x实例和全局x实例不受影响
嵌套_作用域之前 — 在Python 2.1之前版本和2.1版本中,除非您特别要求使用将来导入的 — fun1和fun2的作用域对fun3不可见,因此s.Lott的答案成立,您将得到全局x:
0 0
实际上,Python范围解析的简明规则是。(这些规则特定于变量名,而不是属性。如果引用时没有句点,则适用这些规则。) 立法局规则
- Local—在函数(
或def
)中以任何方式分配的名称,且在该函数中未声明为全局名称lambda
- Enclosing function—在任何和所有静态封闭函数(
或def
)的局部范围内从内部到外部分配的名称lambda
- Global(模块)-在模块文件的顶层分配的名称,或通过在文件中的
中执行def
语句分配的名称global
- B内置(Python)-在内置名称模块中预先分配的名称:
,打开
,范围
,等等语法错误
code1
class Foo:
code2
def spam():
code3
for code4:
code5
x()
for
循环没有自己的命名空间。按照立法顺序,范围将是
- L:def spam中的本地(在
、code3
和code4
中)code5
- E:任何封闭函数(如果整个示例位于另一个
)def
- G:模块(在
中)是否有任何code1
全局声明x
- B:Python中的任何内置
x
在
code2
中永远找不到x
(即使在您可能期望的情况下,也请参见或)。Python 2.x的范围规则已被删除
def foo():
x=4
def bar():
print x # Accesses x from foo's scope
bar() # Prints 4
x=5
bar() # Prints 5
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
global_var = 4
def change_global():
global global_var
global_var = global_var + 1
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)
>>> [ i for i in range(5) ]
>>> i
4
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()
x = 5
def foobar():
global x
print(x)
x += 1
foobar() # -> 5
print(x) # -> 6
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() # -> 5 911
print(x, y) # -> 6 13
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
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.
import __builtin__
print3 = __builtin__.__dict__['print']
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()
┎ builtins [print, ...]
┗━┱ globals [some_global]
┗━┱ outer_function [some_local, some_closure]
┣━╾ InnerClass [some_classvar]
┗━╾ inner_function [some_local]
┎ builtins [print, ...]
┗━┱ globals [some_global]
┗━┱ outer_function [some_closure]
┗━╾ <listcomp> [comp_local]