在python中从全局范围解析变量
我试图更好地理解python中的作用域。我有以下玩具示例:在python中从全局范围解析变量,python,python-2.7,python-2.x,Python,Python 2.7,Python 2.x,我试图更好地理解python中的作用域。我有以下玩具示例: a = 1 print "in global: " + str(a) def g(): a += 1 print "in g(): " + str(a) def f(): a += 1 print "in f(): " + str(a) g() f() 我希望它运行并再次打印出1然后2然后2。但是,我得到了一个错误: UnboundLocalError: local variable '
a = 1
print "in global: " + str(a)
def g():
a += 1
print "in g(): " + str(a)
def f():
a += 1
print "in f(): " + str(a)
g()
f()
我希望它运行并再次打印出1
然后2
然后2
。但是,我得到了一个错误:
UnboundLocalError: local variable 'a' referenced before assignment
我原以为g()
和f()
都会把a
从全局范围中拉出来。不对
更新:
感谢您的回答,但不清楚的是:如果我只想读取全局变量a
,并将其分配给我创建的局部变量,也称为a
,这可能吗
我这样做的原因是我试图弄清楚
g()
在调用时是继承f()
的作用域,还是继承定义它的全局作用域?您需要使用全局
关键字
>>> a = 1
>>> def g():
... global a
... a += 1
... print a
...
>>> g()
2
函数g和f中缺少全局运算符 像这样:
a = 1
def g():
global a
a += 1
print "in g(): " + str(a)
def f():
global a
a += 1
print "in f(): " + str(a)
您可以在和中找到有关全局变量和局部变量的更多信息。如果您试图在函数的外部范围中更改
a
,a
不在当前函数的范围内,这就是为什么会出现这样的错误,因为您的函数对a
一无所知。如果要从函数内部更改a
,则需要使用“全局”:
a = 1
print "in global: " + str(a)
def g():
global a
a += 1
print "in g(): " + str(a)
def f():
global a
a += 1
print "in f(): " + str(a)
g()
要打印全局a
请按以下方式使用:
def f():
print a
new_a = a
print new_a
关于global
如果要使用局部变量a
和全局a
中的值,请使用:
当您请求一个变量值时,Python遵循以下规则:局部、封闭、全局、内置 但当您分配变量时,它是在局部范围内从头创建的(假设变量分配在函数内部),丢弃以前绑定到它的任何值:
a = 5
def f(x):
print a # Prints `5`, because name `a` can be found following LEGB rule in Global scope.
print x # Prints whatever value `x` was having, found following LEGB rule in Local scope.
x = 123 # Forgets previous value of `x`, re-assign it to `123` in the Local scope.
未绑定变量的问题出现在这里:a+=1
只是a=a+1
的一个语法糖。当您执行a=a+1
时,Python捕捉到a
是本地的,因此它以字节码生成LOAD\u FAST命令:
import dis
a = 1
def f():
a += 1
print dis.dis(f)
0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (a)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
LOAD_FAST用于获取局部变量。但是,当调用LOAD\u FAST时,本地作用域中还没有a
,因此命令失败
实际上,如果您没有分配给a
,但希望从本地范围修改它,则可以通过方法调用来完成。不幸的是,int
没有修改方法,因此我将给出一个类的示例:
class Number(object):
def __init__(self, x):
self.x = x
def add_one(self):
self.x += 1
a = Number(1)
def f():
a.add_one()
print a.x
print a.x
f()
print a.x
1
2
2
在这里,您基本上执行
a=a+1
,但方式更为复杂。这是因为对a
的调用被解析为全局调用(工作正常),并且您不在f()
中执行任何赋值。方法add_one
是对现有对象调用的-它不关心调用方中的方法是全局的还是局部的 在第二段代码中,您不需要global
class Number(object):
def __init__(self, x):
self.x = x
def add_one(self):
self.x += 1
a = Number(1)
def f():
a.add_one()
print a.x
print a.x
f()
print a.x
1
2
2