简体   繁体   English

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

[英]Use of "global" keyword in Python

From my understanding, Python has a separate namespace for functions, so if I want to use a global variable in a function, I should probably use global .据我了解,Python 有一个单独的函数命名空间,所以如果我想在函数中使用全局变量,我可能应该使用global

However, I was able to access a global variable even without global :但是,即使没有global ,我也能够访问全局变量:

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

Am I missing anything?我错过了什么吗? Also, following is from Python documentation:此外,以下来自 Python 文档:

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.全局语句中列出的名称不得定义为形式参数或 for 循环控制目标、类定义、函数定义或导入语句。

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.虽然形式参数和类定义对我来说很有意义,但我无法理解 for 循环控制目标和函数定义的限制。

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.关键字global仅对在本地上下文中更改或创建全局变量有用,尽管创建全局变量很少被认为是一个好的解决方案。

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.而如果您使用global语句,则该变量将在函数范围“之外”可用,从而有效地成为全局变量。

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.此外,由于 python 的特性,您还可以使用global在本地上下文中声明函数、类或其他对象。 Although I would advise against it since it causes nightmares if something goes wrong or needs debugging.尽管我建议不要这样做,因为如果出现问题或需要调试,它会导致噩梦。

While you can access global variables without the global keyword, if you want to modify them you have to use the global keyword.虽然您可以在没有global关键字的情况下访问全局变量,但如果要修改它们,则必须使用global关键字。 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 .在您的情况下,您只是访问列表sub

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 (eg UnboundLocalError suddenly appearing in previously working code).绑定块中的任何位置会导致该块中任何位置的名称都被绑定,这可能会导致一些看起来很奇怪的后果(例如 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
>>> 

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.关于 Python 中的名称要了解的另一件重要事情是,它们在每个范围内都是本地的或全局的。

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.您可能会猜到value = 0语句将分配给局部变量,并且不会影响在doit()函数之外声明的同一变量的值。 You may be more surprised to discover that the code above won't run.您可能会更惊讶地发现上面的代码不会运行。 The statement print value inside the function produces an UnboundLocalError.函数内的语句print value会产生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 .原因是 Python 已经注意到,在函数的其他地方,您指定了名称value ,并且value也没有在任何地方声明为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.在这种情况下,Python不会像其他一些语言那样回退到将名称作为全局变量来查找。 Essentially, you cannot access a global variable if you have defined a local variable of the same name anywhere in the function.本质上,如果您在函数的任何位置定义了同名的局部变量,则无法访问全局变量。

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
  • You can access global keywords without keyword global您可以在没有关键字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]

This is explained well in the Python FAQ这在 Python FAQ 中有很好的解释

What are the rules for local and global variables in Python? Python中局部变量和全局变量的规则是什么?

In Python, variables that are only referenced inside a function are implicitly global.在 Python 中,仅在函数内部引用的变量是隐式全局的。 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.一方面,对已分配的变量要求global提供了防止意外副作用的障碍。 On the other hand, if global was required for all global references, you'd be using global all the time.另一方面,如果所有global引用都需要全局,那么您将一直使用global You'd have to declare as global every reference to a built-in function or to a component of an imported module.您必须将对内置函数或导入模块组件的每个引用声明为global This clutter would defeat the usefulness of the global declaration for identifying side-effects.这种混乱会破坏global声明识别副作用的有用性。

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

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

global makes the variable visible to everything in the module , the modular scope , just as if you had defined it at top-level in the module itself. global使该变量对模块中的所有内容(模块化范围)可见,就像您在模块本身的顶层定义它一样。 It's not visible outside the module, and it cannot be imported from the module until after it has been set, so don't bother, that's not what it is for.它在模块之外是不可见的,并且在设置它之前无法从模块中导入,所以不要打扰,这不是它的用途。

When does global solve real problems? global何时解决实际问题? (Note: Checked only on Python 3.) (注意:仅在 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()

This can be fixed with global :这可以用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()

This wouldn't be necessary if bar() was defined inside foo like so:如果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

By defining bar() outside of foo() , bar() can be imported into something that can import catbus directly, or mock it, like in a unit test.通过在foo() bar() ) ,可以将bar()导入到可以直接导入catbus或模拟它的东西中,就像在单元测试中一样。

global is a code smell, but sometimes what you need is exactly a dirty hack like global . global是一种代码味道,但有时您需要的正是像global这样的肮脏黑客。 Anyway, "global" is a bad name for it as there is no such thing as global scope in python, it's modules all the way down.无论如何,“全局”对它来说是个坏名字,因为在 python 中没有全局范围之类的东西,它一直是模块。

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.这使得 'x' 在函数外表现得像一个普通变量。 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)

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"

i will give you a simple example : think about this code : 我会给你一个简单的例子:考虑一下这段代码:

myVar = 0 
print (myVar )      # 01 line: returns 0

def func():
    myVar  = "def"
    print (myVar )

func()              # 02 line: returns def
print (myVar )      # 03 line: returns 0

as you can see the last line of code will returns 0 , because inside the function the myVar variable is not been reassigned , its just been modified and it will changes only when the function called without affecting the main myVar variable , because it defined inside the our function (means it is local variable) , but with using global keyword as such : 如您所见,代码的最后一行将返回0,因为未在函数内部重新分配myVar变量,只是对其进行了修改,并且仅在调用函数时才会更改,而不会影响主myVar变量,因为它在我们的函数(意味着它是局部变量) ,但是使用了global关键字:

 myVar  = 0 
print (myVar )       # 01 Line : returns 0

def func():
    global myVar 
    myVar  = "def"
    print (myVar )

func()               # 02 Line : returns def
print (myVar )       # 03 Line : returns def

we actually ordering python that this variable inside def is not local , use global variable named as myVar as change it. 我们实际上是在命令python,使def中的此变量不是局部变量,请使用名为myVar的全局变量进行更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM