问题:Python函数全局变量?

我知道我应该避免由于此类混淆而首先使用全局变量,但是如果我要使用它们,以下是使用它们的有效方法吗?(我正在尝试调用在单独函数中创建的变量的全局副本。)

x = "somevalue"

def func_A ():
   global x
   # Do things to x
   return x

def func_B():
   x = func_A()
   # Do things
   return x

func_A()
func_B()

请问x第二函数使用具有全球复制相同的值xfunc_a使用和修改?定义后调用函数时,顺序重要吗?

I know I should avoid using global variables in the first place due to confusion like this, but if I were to use them, is the following a valid way to go about using them? (I am trying to call the global copy of a variable created in a separate function.)

x = "somevalue"

def func_A ():
   global x
   # Do things to x
   return x

def func_B():
   x = func_A()
   # Do things
   return x

func_A()
func_B()

Does the x that the second function uses have the same value of the global copy of x that func_a uses and modifies? When calling the functions after definition, does order matter?


回答 0

如果只想访问全局变量,则只需使用其名称即可。但是,要更改其值,您需要使用global关键字。

例如

global someVar
someVar = 55

这会将全局变量的值更改为55。否则,它将仅将55分配给局部变量。

函数定义列表的顺序无关紧要(假设它们在某种程度上没有相互引用),被调用的顺序确实如此。

If you want to simply access a global variable you just use its name. However to change its value you need to use the global keyword.

E.g.

global someVar
someVar = 55

This would change the value of the global variable to 55. Otherwise it would just assign 55 to a local variable.

The order of function definition listings doesn’t matter (assuming they don’t refer to each other in some way), the order they are called does.


回答 1

在Python范围内,对未在该范围内声明的变量的任何赋值都会创建一个新的局部变量,除非该变量在函数中较早地声明为使用关键字引用了全局范围的变量global

让我们看一下伪代码的修改版本,看看会发生什么:

# Here, we're creating a variable 'x', in the __main__ scope.
x = 'None!'

def func_A():
  # The below declaration lets the function know that we
  #  mean the global 'x' when we refer to that variable, not
  #  any local one

  global x
  x = 'A'
  return x

def func_B():
  # Here, we are somewhat mislead.  We're actually involving two different
  #  variables named 'x'.  One is local to func_B, the other is global.

  # By calling func_A(), we do two things: we're reassigning the value
  #  of the GLOBAL x as part of func_A, and then taking that same value
  #  since it's returned by func_A, and assigning it to a LOCAL variable
  #  named 'x'.     
  x = func_A() # look at this as: x_local = func_A()

  # Here, we're assigning the value of 'B' to the LOCAL x.
  x = 'B' # look at this as: x_local = 'B'

  return x # look at this as: return x_local

实际上,您可以func_B使用named变量重写所有变量,x_local并且其工作方式相同。

该顺序仅与函数执行更改全局x值的操作的顺序一样重要。因此,在我们的示例中,顺序没有关系,因为func_Bcall func_A。在此示例中,顺序很重要:

def a():
  global foo
  foo = 'A'

def b():
  global foo
  foo = 'B'

b()
a()
print foo
# prints 'A' because a() was the last function to modify 'foo'.

请注意,global仅需要修改全局对象。您仍然可以从函数内部访问它们而无需声明global。因此,我们有:

x = 5

def access_only():
  return x
  # This returns whatever the global value of 'x' is

def modify():
  global x
  x = 'modified'
  return x
  # This function makes the global 'x' equal to 'modified', and then returns that value

def create_locally():
  x = 'local!'
  return x
  # This function creates a new local variable named 'x', and sets it as 'local',
  #  and returns that.  The global 'x' is untouched.

请注意,create_locallyaccess_only– 之间的区别access_only是尽管未调用global,但仍访问全局x ,即使create_locally不使用global任何一个,它也会由于分配值而创建本地副本。

这里的困惑是为什么您不应该使用全局变量。

Within a Python scope, any assignment to a variable not already declared within that scope creates a new local variable unless that variable is declared earlier in the function as referring to a globally scoped variable with the keyword global.

Let’s look at a modified version of your pseudocode to see what happens:

# Here, we're creating a variable 'x', in the __main__ scope.
x = 'None!'

def func_A():
  # The below declaration lets the function know that we
  #  mean the global 'x' when we refer to that variable, not
  #  any local one

  global x
  x = 'A'
  return x

def func_B():
  # Here, we are somewhat mislead.  We're actually involving two different
  #  variables named 'x'.  One is local to func_B, the other is global.

  # By calling func_A(), we do two things: we're reassigning the value
  #  of the GLOBAL x as part of func_A, and then taking that same value
  #  since it's returned by func_A, and assigning it to a LOCAL variable
  #  named 'x'.     
  x = func_A() # look at this as: x_local = func_A()

  # Here, we're assigning the value of 'B' to the LOCAL x.
  x = 'B' # look at this as: x_local = 'B'

  return x # look at this as: return x_local

In fact, you could rewrite all of func_B with the variable named x_local and it would work identically.

The order matters only as far as the order in which your functions do operations that change the value of the global x. Thus in our example, order doesn’t matter, since func_B calls func_A. In this example, order does matter:

def a():
  global foo
  foo = 'A'

def b():
  global foo
  foo = 'B'

b()
a()
print foo
# prints 'A' because a() was the last function to modify 'foo'.

Note that global is only required to modify global objects. You can still access them from within a function without declaring global. Thus, we have:

x = 5

def access_only():
  return x
  # This returns whatever the global value of 'x' is

def modify():
  global x
  x = 'modified'
  return x
  # This function makes the global 'x' equal to 'modified', and then returns that value

def create_locally():
  x = 'local!'
  return x
  # This function creates a new local variable named 'x', and sets it as 'local',
  #  and returns that.  The global 'x' is untouched.

Note the difference between create_locally and access_onlyaccess_only is accessing the global x despite not calling global, and even though create_locally doesn’t use global either, it creates a local copy since it’s assigning a value.

The confusion here is why you shouldn’t use global variables.


回答 2

正如其他人指出的那样,global当您希望该函数能够修改全局变量时,需要在该函数中声明一个变量。如果您只想访问它,则不需要global

为了对此进行更详细的说明,“修改”的含义是:如果要重新绑定全局名称,使其指向另一个对象,则必须global在函数中声明该名称。

许多修改(更改)对象的操作不会重新绑定全局名称以指向其他对象,因此它们在不声明函数名称的情况下都是有效global的。

d = {}
l = []
o = type("object", (object,), {})()

def valid():     # these are all valid without declaring any names global!
   d[0] = 1      # changes what's in d, but d still points to the same object
   d[0] += 1     # ditto
   d.clear()     # ditto! d is now empty but it`s still the same object!
   l.append(0)   # l is still the same list but has an additional member
   o.test = 1    # creating new attribute on o, but o is still the same object

As others have noted, you need to declare a variable global in a function when you want that function to be able to modify the global variable. If you only want to access it, then you don’t need global.

To go into a bit more detail on that, what “modify” means is this: if you want to re-bind the global name so it points to a different object, the name must be declared global in the function.

Many operations that modify (mutate) an object do not re-bind the global name to point to a different object, and so they are all valid without declaring the name global in the function.

d = {}
l = []
o = type("object", (object,), {})()

def valid():     # these are all valid without declaring any names global!
   d[0] = 1      # changes what's in d, but d still points to the same object
   d[0] += 1     # ditto
   d.clear()     # ditto! d is now empty but it`s still the same object!
   l.append(0)   # l is still the same list but has an additional member
   o.test = 1    # creating new attribute on o, but o is still the same object

回答 3

这是一种使用全局变量作为参数默认值的情况,吸引了我。

globVar = None    # initialize value of global variable

def func(param = globVar):   # use globVar as default value for param
    print 'param =', param, 'globVar =', globVar  # display values

def test():
    global globVar
    globVar = 42  # change value of global
    func()

test()
=========
output: param = None, globVar = 42

我曾期望param的值为42。首次解析函数func时,Python 2.7评估了globVar的值。更改globVar的值不会影响分配给param的默认值。如下所示,延迟评估可以按照我的需要进行。

def func(param = eval('globVar')):       # this seems to work
    print 'param =', param, 'globVar =', globVar  # display values

或者,如果您想安全,

def func(param = None)):
    if param == None:
        param = globVar
    print 'param =', param, 'globVar =', globVar  # display values

Here is one case that caught me out, using a global as a default value of a parameter.

globVar = None    # initialize value of global variable

def func(param = globVar):   # use globVar as default value for param
    print 'param =', param, 'globVar =', globVar  # display values

def test():
    global globVar
    globVar = 42  # change value of global
    func()

test()
=========
output: param = None, globVar = 42

I had expected param to have a value of 42. Surprise. Python 2.7 evaluated the value of globVar when it first parsed the function func. Changing the value of globVar did not affect the default value assigned to param. Delaying the evaluation, as in the following, worked as I needed it to.

def func(param = eval('globVar')):       # this seems to work
    print 'param =', param, 'globVar =', globVar  # display values

Or, if you want to be safe,

def func(param = None)):
    if param == None:
        param = globVar
    print 'param =', param, 'globVar =', globVar  # display values

回答 4

您可以直接访问函数内部的全局变量。如果要更改该全局变量的值,请使用“ global variable_name”。请参见以下示例:

var = 1
def global_var_change():
      global var
      var = "value changed"
global_var_change() #call the function for changes
print var

一般来说,这不是一个好的编程习惯。通过破坏命名空间逻辑,代码可能变得难以理解和调试。

You can directly access a global variable inside a function. If you want to change the value of that global variable, use “global variable_name”. See the following example:

var = 1
def global_var_change():
      global var
      var = "value changed"
global_var_change() #call the function for changes
print var

Generally speaking, this is not a good programming practice. By breaking namespace logic, code can become difficult to understand and debug.


回答 5

global当您希望更改分配给全局变量的值时,必须使用声明。

您不需要它来读取全局变量。请注意,在对象上调用方法(即使它更改了该对象内的数据)也不会更改保存该对象的变量的值(缺少反射魔术)。

You must use the global declaration when you wish to alter the value assigned to a global variable.

You do not need it to read from a global variable. Note that calling a method on an object (even if it alters the data within that object) does not alter the value of the variable holding that object (absent reflective magic).


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。