在python中解析来自全局范围的变量

时间:2016-02-10 03:10:11

标签: 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' referenced before assignment

我原以为g()f()都会从全局范围中提取a。不正确的?

更新: 感谢您的回答,但不清楚的是:如果我只想读取全局变量a并将其分配给我创建的局部变量,那么也可以命名为a

我这样做的原因是我试图弄清g()在调用f()时是继承let currentLayerTime = myLayer.convertTime(CACurrentMediaTime(), from: nil) 的范围还是在定义它时的全局范围?

4 个答案:

答案 0 :(得分:5)

您正在尝试更改功能外部范围内的aa不在当前功能范围内,这就是您遇到此类错误的原因,因为您的功能已知什么都不是a。如果你想从函数中改变a,你需要使用`global':

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 here

,有一个很好的例子

如果您想使用来自全球a的值的本地变量a,请使用globals

def g():  
    a = globals()['a']
    a += 1
    print "in g(): " + str(a)

答案 1 :(得分:4)

您需要使用global关键字。

>>> a = 1         
>>> def g():      
...     global a  
...     a += 1    
...     print a   
...               
>>> g()           
2    

答案 2 :(得分:4)

你缺少函数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)

您可以在documentation herestack overflow here

中找到有关全局和局部变量的更多信息

答案 3 :(得分:1)

当你要求变量值时,Python遵循LEGB规则:local,enclosing,global,built-in。

但是当你分配一个变量时,它在本地范围内被创建从头开始(假设变量赋值在函数内部),丢弃以前绑定到它的任何值:

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_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_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 - 它不关心它在调用者中是全局的还是本地的。