作用域
python仅有
LEGB四种作用域,意味着if/else与while等语句不会产生新的作用域
LEGBL:LocalE:EnclosingG:GlobalB:Builtin
四种作用域相关
globalVar = 1 # G for any,L for module
def func():
funcLocalVar = 2 # E for inner() below, L for func()
def inner():
innerLocalVar = 3 # L for inner()
print __name__ # B
- 对于
LEGB,仅有当变量在该域内的作用域类型为L时才可进行读写; 对于其他类型都是仅可读,每次尝试写入都是新声明 =Declare on Write
G <Global>相关说明
代码:
# Declare a globalVar
globalVar = 1 # G for any,L for module
def globalFunc():
globalVar = 2 # Try to write globalVar.
print globalVar # output: 2
# globalFunc() trying to write globalVar
globalFunc()
# Print globalVar in module
print globalVar # output: 1. Means that the globalVar hasn't been written.
# Write globalVar in module.
globalVar = 3
# Print globalVar in module
print globalVar # output: 3. Means that the globalVar has been written.
# Noticed that globalVar in module is G for globalFunc(), so writing in globalFunc equals declaring.
# And after declaring, globalVar now is L for globalFunc
结论:
- 全局
globalVar对于globalFunc而言作用域类型是为G,故在globalFunc内进行写入视为声明 - 而在声明后,方法内部的
globalVar成为局部变量,独立于全局版本
E <Enclosing>相关说明
代码:
# Keeping same with Global
def enclosingFunc():
funcLocalVar = 1 # E for inner() below, L for enclosingFunc()
def inner():
funcLocalVar = 2 # Try to write funcLocalVar.
print funcLocalVar # output: 2
# inner() trying to write funcLocalVar
inner()
print funcLocalVar # output: 1. Means that the globalVar hasn't been written.
# etc...
enclosingFunc()
# Statements keep with Global
结论:
- 结论与
Global基本一致,可类推,不赘述。
- 想要修改其他类型的变量时,使用global/nonlocal等修饰符引入变量
global= 修改Globalnonlocal= 修改Enclosing [python3.x]
以Global举例代码
# Declare a globalVar
globalVar = 1 # G for any,L for module
def globalFunc1():
global globalVar # G for globalFunc1. Use global will declare globalVar to this method.
globalVar = 2 # Try to write globalVar. We can actually write for it's declared.
print globalVar # output: 2
# globalFunc() trying to write globalVar
globalFunc()
# Print globalVar in module
print globalVar # output: 2. Means that the globalVar has been written.
- QA
- 问:如果希望在
python2.x中达到nonlocal的效果,有什么方法吗? 答:无官方支持,但实现上可以在闭包将要使用的对象上使用一层对象或者词典进行包装。如:
# Declare DataWrapper to wrap our enclosing data.
class DataWrapper(object):
def __init__(self, var):
self.var = var
# Keeping same with Global
def enclosingFunc():
funcLocal = DataWrapper(1) # Declare funcLocal as DataWrapper, and take our data as DataWrapper field.
def inner():
funcLocal.var = 2 # Try to write funcLocal.var.
print funcLocal.var # output: 2
# inner() trying to write funcLocalVar
inner()
print funcLocal.var # output: 2. Means that the funcLocal.var has been written.
enclosingFunc()