在Python中使用“全局”关键字

问题:在Python中使用“全局”关键字

通过阅读文档,我了解到Python具有一个单独的函数命名空间,如果我想在该函数中使用全局变量,则需要使用global

我正在使用Python 2.7,并且尝试了这个小测试

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

即使没有,看起来一切都很好global。我能够毫无问题地访问全局变量。

我有什么想念的吗?另外,以下是Python文档中的内容:

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

尽管形式参数和类定义对我来说很有意义,但我无法理解对循环控制目标和函数定义的限制。

What I understand from reading the documentation is that Python has a separate namespace for functions, and if I want to use a global variable in that function, I need to use global.

I’m using Python 2.7 and I tried this little test

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

It seems things are working fine even without global. I was able to access global variable without any problem.

Am I missing anything? Also, following is from Python documentation:

Names listed in a global statement must not be defined as formal parameters or in a for loop control target, class definition, function definition, or import statement.

While formal parameters and class definition make sense to me, I’m not able to understand the restriction on for loop control target and function definition.


回答 0

关键字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

如果使用该global语句,则变量将在函数范围之外“可用”,从而有效地成为全局变量。

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在局部上下文中声明函数,类或其他对象。尽管我会建议不要这样做,因为如果出现问题或需要调试,它会引起噩梦。

The keyword global is only useful to change or create global variables in a local context, although creating global variables is seldom considered a good solution.

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

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

The above will give you:

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

While if you use the global statement, the variable will become available “outside” the scope of the function, effectively becoming a global variable.

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

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

So the above code will give you:

locally defined
locally defined

In addition, due to the nature of python, you could also use global to declare functions, classes or other objects in a local context. Although I would advise against it since it causes nightmares if something goes wrong or needs debugging.


回答 1

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

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

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

就您而言,您只是在访问列表sub

While you can access global variables without the global keyword, if you want to modify them you have to use the global keyword. For example:

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

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

In your case, you’re just accessing the list sub.


回答 2

这是访问名称并将其绑定到作用域之间的区别。

如果只是查找变量以读取其值,则可以访问全局范围和局部范围。

但是,如果您将变量名分配给不在本地范围内的变量,则会将该名称绑定到该范围内(并且如果该名称也作为全局变量存在,则将其隐藏)。

如果希望能够分配给全局名称,则需要告诉解析器使用全局名称,而不是绑定新的本地名称,这就是’global’关键字的作用。

在一个块中的任何地方绑定都会导致该块中每个地方的名称都被绑定,这可能会导致一些看起来很奇怪的后果(例如,UnboundLocalError突然出现在以前的工作代码中)。

>>> a = 1
>>> def p():
    print(a) # accessing global scope, no binding going on
>>> def q():
    a = 3 # binding a name in local scope - hiding global
    print(a)
>>> def r():
    print(a) # fail - a is bound to local scope, but not assigned yet
    a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    r()
  File "<pyshell#32>", line 2, in r
    print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>> 

This is the difference between accessing the name and binding it within a scope.

If you’re just looking up a variable to read its value, you’ve got access to global as well as local scope.

However if you assign to a variable who’s name isn’t in local scope, you are binding that name into this scope (and if that name also exists as a global, you’ll hide that).

If you want to be able to assign to the global name, you need to tell the parser to use the global name rather than bind a new local name – which is what the ‘global’ keyword does.

Binding anywhere within a block causes the name everywhere in that block to become bound, which can cause some rather odd looking consequences (e.g. UnboundLocalError suddenly appearing in previously working code).

>>> a = 1
>>> def p():
    print(a) # accessing global scope, no binding going on
>>> def q():
    a = 3 # binding a name in local scope - hiding global
    print(a)
>>> def r():
    print(a) # fail - a is bound to local scope, but not assigned yet
    a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    r()
  File "<pyshell#32>", line 2, in r
    print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>> 

回答 3

其他答案回答您的问题。关于Python的名称,要知道的另一件重要事情是,就每个作用域而言,它们是局部的还是全局的。

考虑一下,例如:

value = 42

def doit():
    print value
    value = 0

doit()
print value

您可能会猜到该value = 0语句将分配给局部变量,而不会影响在doit()函数外部声明的同一变量的值。您可能会惊讶地发现上面的代码无法运行。print value函数内部的语句产生一个UnboundLocalError.

原因是Python注意到在函数的其他地方,您分配了名称value,并且也value未声明global。这使其成为局部变量。但是,当您尝试打印它时,尚未定义本地名称。在这种情况下 Python 不会像其他一些语言那样将名称作为全局变量来查找。本质上,如果您在函数中的任何位置定义了具有相同名称的局部变量,则无法访问全局变量。

The other answers answer your question. Another important thing to know about names in Python is that they are either local or global on a per-scope basis.

Consider this, for example:

value = 42

def doit():
    print value
    value = 0

doit()
print value

You can probably guess that the value = 0 statement will be assigning to a local variable and not affect the value of the same variable declared outside the doit() function. You may be more surprised to discover that the code above won’t run. The statement print value inside the function produces an UnboundLocalError.

The reason is that Python has noticed that, elsewhere in the function, you assign the name value, and also value is nowhere declared global. That makes it a local variable. But when you try to print it, the local name hasn’t been defined yet. Python in this case does not fall back to looking for the name as a global variable, as some other languages do. Essentially, you cannot access a global variable if you have defined a local variable of the same name anywhere in the function.


回答 4

访问名称和分配名称是不同的。就您而言,您只是在访问一个名称。

如果在函数内分配变量,除非您声明全局变量,否则假定该变量为局部变量。如果没有,则假定它是全局的。

>>> x = 1         # global 
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():   
        x = 2        # local x
        print x 

>>> x            # global x
1
>>> foo()        # prints local x
2

Accessing a name and assigning a name are different. In your case, you are just accessing a name.

If you assign to a variable within a function, that variable is assumed to be local unless you declare it global. In the absence of that, it is assumed to be global.

>>> x = 1         # global 
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():   
        x = 2        # local x
        print x 

>>> x            # global x
1
>>> foo()        # prints local x
2

回答 5

  • 您可以访问不带关键字的全局关键字 global
  • 为了能够修改它们,您需要明确声明该关键字是全局的。否则,将在本地范围内声明关键字。

例:

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]
  • You can access global keywords without keyword global
  • To be able to modify them you need to explicitly state that the keyword is global. Otherwise, the keyword will be declared in local scope.

Example:

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]

回答 6

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

Any variable declared outside of a function is assumed to be global, it’s only when declaring them from inside of functions (except constructors) that you must specify that the variable be global.


回答 7

Python常见问题解答对此进行了很好的解释

Python中局部和全局变量的规则是什么?

在Python中,仅在函数内部引用的变量是隐式全局的。如果在函数体内任何位置为变量分配了值,除非明确声明为全局变量,否则将假定该变量为局部变量。

尽管起初有些令人惊讶,但片刻的考虑可以解释这一点。一方面,要求global分配变量可防止意外副作用。另一方面,如果global所有全局引用都需要,那么您将一直使用global。您必须声明作为global对内置函数或对导入模块的组件的每个引用。这种混乱将破坏global声明对确定副作用的有用性。

https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

This is explained well in the Python FAQ

What are the rules for local and global variables in Python?

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Though a bit surprising at first, a moment’s consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you’d be using global all the time. You’d have to declare as global every reference to a built-in function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python


回答 8

这意味着您不应执行以下操作:

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"

It means that you should not do the following:

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"

回答 9

全局使变量“全局”

def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

这使“ x”的作用类似于函数外部的普通变量。如果您删除了全局变量,那么它将给出一个错误,因为它无法在函数内部打印变量。

def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)

Global makes the variable “Global”

def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

This makes ‘x’ act like a normal variable outside the function. If you took the global out then it would give an error since it cannot print a variable inside a function.

def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)