根据我的理解,Python有一个单独的函数名称空间,所以如果我想在函数中使用全局变量,我可能应该使用global。

然而,我能够访问一个全局变量,即使没有全局:

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

为什么会这样?


另请参阅第一次使用后重新分配局部变量时发生的UnboundLocalError,以了解试图分配给全局变量而不使用全局变量时发生的错误。有关如何使用全局变量的一般问题,请参阅在函数中使用全局变量。


当前回答

关键字global仅用于在局部上下文中更改或创建全局变量,尽管创建全局变量很少被认为是一个好的解决方案。

def bob():
    me = "locally defined"    # Defined only in local context
    print(me)

bob()
print(me)     # Asking for a global variable

以上会给你:

locally defined
Traceback (most recent call last):
  File "file.py", line 9, in <module>
    print(me)
NameError: name 'me' is not defined

而如果使用全局语句,则变量将在函数作用域之外可用,有效地成为全局变量。

def bob():
    global me
    me = "locally defined"   # Defined locally but declared as global
    print(me)

bob()
print(me)     # Asking for a global variable

所以上面的代码会给你:

locally defined
locally defined

此外,由于python的特性,您还可以使用global在局部上下文中声明函数、类或其他对象。尽管我建议不要这样做,因为如果出现错误或需要调试,这会导致噩梦。

其他回答

这意味着你不应该做以下事情:

x = 1

def myfunc():
  global x

  # formal parameter
  def localfunction(x):
    return x+1

  # import statement
  import os.path as x

  # for loop control target
  for x in range(10):
    print x

  # class definition
  class x(object):
    def __init__(self):
      pass

  #function definition
  def x():
    print "I'm bad"

在函数外部声明的任何变量都被假定为全局变量,只有在函数内部声明它们时(构造函数除外),你必须指定变量为全局变量。

如果没有全局关键字,可以访问全局关键字 为了能够修改它们,您需要显式地声明关键字是全局的。否则,关键字将在局部范围内声明。

例子:

words = [...] 

def contains (word): 
    global words             # <- not really needed
    return (word in words) 

def add (word): 
    global words             # must specify that we're working with a global keyword
    if word not in words: 
        words += [word]

虽然你可以在没有global关键字的情况下访问全局变量,但如果你想修改它们,你必须使用global关键字。例如:

foo = 1
def test():
    foo = 2 # new local foo

def blub():
    global foo
    foo = 3 # changes the value of the global foo

在这里,你只是访问了list sub。

Global使变量对模块(模块作用域)中的所有内容可见,就像您在模块本身的顶层定义了它一样。它在模块外部是不可见的,在它被设置之前,它不能从模块中导入,所以不用麻烦,这不是它的用途。

全球何时能解决实际问题?(注意:仅在Python 3上检查。)

# Attempt #1, will fail
# We cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to 
# do it automatically  when importing this module

top_level_something_or_other = None

def foo1():
    import catbus
    # Now ``catbus`` is visible for anything else defined inside ``foo()`` 
    # at *compile time*
    bar()  # But ``bar()`` is a call, not a definition. ``catbus`` 
           # is invisible to it.

def bar():
    # `bar()` sees what is defined in the module
    # This works:
    print(top_level_something_or_other)
    # This doesn't work, we get an exception: NameError: name 'catbus' is not defined
    catbus.run()

这可以用global来修复:

# Attempt #2, will work
# We still cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to 
# do it automatically  when importing this module

top_level_something_or_other = None

def foo2():
    import catbus
    global catbus  # Now catbus is also visible to anything defined 
                   # in the top-level module *at runtime* 
    bar()

def bar():
    # `bar` sees what is defined in the module and when run what is available at run time
    # This still works:
    print(top_level_something_or_other)
    # This also works now:
    catbus.run()

如果bar()在foo中定义,这就不需要了:

# Attempt 3, will work
# We cannot import ``catbus`` here
# as that would lead to an import loop somewhere else,
# or importing ``catbus`` is so expensive that you don't want to 
# do it automatically  when importing this module

top_level_something_or_other = None

def foo3():

    def bar():
        # ``bar()`` sees what is defined in the module *and* what is defined in ``foo()``
        print(top_level_something_or_other)
        catbus.run()

    import catbus
    # Now catbus is visible for anything else defined inside foo() at *compile time*
    bar()  # Which now includes bar(), so this works

通过在foo()之外定义bar(), bar()可以被导入到可以直接导入catbus的东西中,或者在单元测试中模拟它。

全局是一种代码气味,但有时你需要的正是像全局这样的肮脏黑客。不管怎样,“global”对它来说是个坏名字,因为在python中没有全局作用域这样的东西,它一直是模块。