Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用“global”关键字_Python_Global Variables - Fatal编程技术网

在Python中使用“global”关键字

在Python中使用“global”关键字,python,global-variables,Python,Global Variables,通过阅读文档,我了解到Python有一个单独的函数名称空间,如果我想在该函数中使用全局变量,我需要使用全局变量 我正在使用Python2.7,我尝试了这个小测试 >>> sub = ['0', '0', '0', '0'] >>> def getJoin(): ... return '.'.join(sub) ... >>> getJoin() '0.0.0.0' 即使没有全球合作,情况似乎也很好。我能够毫无问题地访问全局变量 我遗

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

我正在使用Python2.7,我尝试了这个小测试

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'
即使没有全球合作,情况似乎也很好。我能够毫无问题地访问全局变量

我遗漏了什么吗?另外,以下内容来自Python文档:

全局语句中列出的名称 不能被定义为正式的 参数或在for循环控制中 目标、类定义、函数 定义或导入语句


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

访问名称和分配名称是不同的。在您的情况下,您只是访问一个名称

如果指定给函数中的某个变量,则假定该变量为局部变量,除非将其声明为全局变量。如果没有这一点,则假定它是全球性的

>>> 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

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

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

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

def doit():
    print value
    value = 0

doit()
print value

在您的情况下,您只是在访问列表子部分。

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

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

>>> 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
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"
关键字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
locally defined
locally defined
因此,上述代码将为您提供:

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

此外,由于python的性质,您还可以使用global在本地上下文中声明函数、类或其他对象。尽管我建议不要使用它,因为如果出现问题或需要调试,它会导致噩梦。

这就是访问名称和在范围内访问名称之间的区别

如果您只是查找一个变量来读取其值,那么您可以访问全局范围和局部范围

但是,如果您分配给一个名称不在本地范围内的变量,则您将该名称绑定到此范围中,如果该名称也作为全局名称存在,则您将隐藏该名称

如果您希望能够分配给全局名称,则需要告诉解析器使用全局名称,而不是绑定新的本地名称——“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
>>> 

其他答案回答了你的问题。关于Python中的名称,需要知道的另一件重要事情是,它们在每个作用域的基础上是局部的或全局的

例如,考虑这一点:

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

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

def doit():
    print value
    value = 0

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

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

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)
您可以访问全局关键字,而无需全局关键字 为了能够修改它们,您需要显式地声明关键字是全局的。否则,关键字将在本地范围内声明。 例如:

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]

全局使变量成为全局变量

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)

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

Python中局部变量和全局变量的规则是什么? 在Python中,仅在函数内部引用的变量是隐式全局变量。如果在函数体中的任何位置为变量赋值,则假定该变量为局部变量,除非显式声明为全局变量

虽然一开始有点令人惊讶,但经过片刻的考虑就可以解释这一点。一方面,为指定的变量要求全局变量提供了防止意外副作用的屏障。另一方面,如果所有全局引用都需要global,那么您将一直使用global。您必须将对内置函数或组件的每个引用声明为全局引用 导入的模块的名称。这种混乱将破坏《全球宣言》在确定副作用方面的作用


我想您可能会对php感到困惑,因为php需要使用全局关键字—python文档证实了这一点—基本上,如果它没有在本地上下文中定义,它将被视为全局的—请注意您的措辞:python没有单独的函数名称空间,这意味着您可以使用def foo:。。。和foo=。。。同时它确实为每个函数调用创建了一个新的作用域。但是,这与世界上所有其他远程高级语言有什么不同呢?ikostia列举了所有你不能使用“x”的东西,因为你使用了global-@Unode:我只是在演示NikhilRathod在引用中给出的所有案例。谢谢你指出这一点。因此,只要您的本地作用域没有分配给存在于其外部的名称,那么本地作用域中的引用将使用外部名称。但是,如果在函数中的任何地方指定了该名称,那么即使在本地指定之前,该本地范围中的引用也不会向外看。确切地说,您已经得到了它。Python 3.x中的全局或非局部覆盖此行为,并允许您重新分配外部名称。在其他语言中,这似乎被称为提升,例如:以牙还牙,用更新的JavaScript关键字声明的变量不会被吊起。访问全局变量的全局变量是否更快,或者无所谓?在这个上下文中,全局看起来不同于考虑全局的其他语言。在Python中,全局引用仍然在模块的范围内,需要从该模块外部作为module.global_var引用,而不是像人们所期望的那样简单地作为global_var引用。@juice-在Python中,谢天谢地,没有在所有名称空间中自动定义绝对全局的东西。正如您正确指出的,全局变量绑定到模块内的名称空间,但是它可以从module import variable或import module.variable导入到另一个模块中。在第一种情况下,导入将使变量可以作为变量访问,而不需要作为模块引用。。如果它在模块范围内被视为全局,则将取决于它的导入位置。在Python3中,nonlocal是一个新的与作用域相关的关键字。您能解释一下为什么全局变量不是一个好的解决方案吗?我经常听到这个,但在我目前的项目中,他们似乎正是我需要他们做的。还有什么我没有想到的更险恶的事情吗?@RobinNewwhouse关于SO已经覆盖和其他非SO的问题有一些。@phoenix sooo global基本上只对从局部范围内定义或启动全局变量有用?有一个警告:没有全局工作,foo=3,但是foo是在blub函数作用域中本地定义的&不修改原始foo变量。这让我很困惑。@chhantyal如果您所说的works是指它没有抛出错误,那么您是正确的,但在Ivo-Wetzel的上下文中,它不会按预期运行。这种行为是有用途的,但它通常不是程序员想要的。有人能解释一下@chhantyal或@democidist的评论吗?当我用Python3尝试这段代码并调用blub时,函数外部的foo确实会按预期绑定到3。@LarryEngholm,blub按预期工作。这是一个没有的测试:创建了新的本地foo,全局foo保留值。请记住,dict值或索引列表值即使没有global关键字也会更改。非常违反直觉,很难相信这是有效的python代码