恢复'global <var>'语句</var>

时间:2010-10-13 08:13:51

标签: python scope global local

我正在学习Python,只是有了这个问题。它可能没有实际价值,我问这个可能是因为迂腐的好奇心。

我有一个功能:

def f():
    x = 12    #this is a local variable
    global x  #this is a global I declared before
    x = 14    #changes global x

    <How can I return the local x?>

我知道这很难看,我确实收到了语法警告。只是想知道如何“取回”我的本地变量。

感谢大家。

3 个答案:

答案 0 :(得分:7)

您的代码没有按照您的想法进行操作,并且没有办法根据您的描述进行更改。你无法“恢复”globals所做的事情,因为它在运行时没有效果。

global关键字在编译时解释,因此在f()的第一行设置x = 12这是修改全局x因为编译器已经决定x在整个函数中引用全局命名空间中的x,而不仅仅是在global语句之后。

您可以轻松测试:

>>> def g():
...     x = 12
...     y = 13
...     global x
...     print "locals:",locals()
...
<stdin>:4: SyntaxWarning: name 'x' is assigned to before global declaration
>>> g()
locals: {'y': 13}

locals() function为我们提供了本地命名空间的视图,我们可以看到其中没有x

The documentation says the following

  

global语句中列出的名称不得在文本上位于global语句之前的相同代码块中使用。

     

global语句中列出的名称不得定义为形式参数或for循环控制目标,class定义,函数定义或import语句。

     

当前的实现并没有强制执行后两个限制,但是程序不应该滥用这种自由,因为未来的实现可能会强制执行它们或者默默地改变程序的含义。

只需为局部变量命名即可。

答案 1 :(得分:4)

我非常怀疑它可以做到。

>>> x = 1
>>> def f():
...     x = 12
...     global x
...     print x
... 
<stdin>:3: SyntaxWarning: name 'x' is assigned to before global declaration
>>> f()
12
>>> x
12

如您所见,即使没有x关键字后global的明确赋值,python也会同步两者的值。要知道原因,你必须拆卸它。

>>> dis.dis(f) # different f with print statement removed for clarity
  2           0 LOAD_CONST               1 (12)
              3 STORE_GLOBAL             0 (x)

  3           6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        
>>> 

此处未显示global关键字,但赋值语句编译为STORE_GLOBAL。完成后,就完成了。小心使用全局变量,并谨慎使用global关键字。

答案 2 :(得分:1)

无法撤消global声明的效果。

global语句适用于它出现的函数的整个持续时间,无论函数在何处,无论它是否被执行。因此,例如,在以下函数的赋值中:

def f():
    x = 3
    if False:
        global x

x仍被视为全球。

因此,之后有另一个语句撤消其效果是没有意义的,因为global“语句”不是一个语句,它在函数期间的某个时刻执行,作为声明关于整个职能的行为。