Python函数全局变量?

Python函数全局变量?,python,global-variables,Python,Global Variables,我知道我应该首先避免使用全局变量,因为这样会产生混淆,但是如果我要使用它们,下面的方法是否是使用它们的有效方法?(我试图调用在单独函数中创建的变量的全局副本。) 第二个函数使用的x是否与func\u a使用和修改的x全局副本的值相同?在定义后调用函数时,顺序是否重要?如果只想访问全局变量,只需使用其名称即可。但是,要更改其值,您需要使用关键字 例如 这会将全局变量的值更改为55。否则它只会将55赋值给一个局部变量 函数定义列表的顺序并不重要(假设它们在某种程度上不相互引用),调用它们的顺序也不重

我知道我应该首先避免使用全局变量,因为这样会产生混淆,但是如果我要使用它们,下面的方法是否是使用它们的有效方法?(我试图调用在单独函数中创建的变量的全局副本。)


第二个函数使用的
x
是否与
func\u a
使用和修改的
x
全局副本的值相同?在定义后调用函数时,顺序是否重要?

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

例如

这会将全局变量的值更改为55。否则它只会将55赋值给一个局部变量


函数定义列表的顺序并不重要(假设它们在某种程度上不相互引用),调用它们的顺序也不重要。

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


从全局变量读取时不需要它。请注意,在对象上调用方法(即使它改变了该对象中的数据)不会改变保存该对象的变量的值(没有反射魔法)。

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

更详细地说,“modify”的意思是:如果要重新绑定全局名称,使其指向不同的对象,则必须在函数中声明名称
global

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()
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
许多修改(变异)对象的操作不会重新绑定全局名称以指向不同的对象,因此它们都是有效的,而无需在函数中声明名称
global

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

在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
事实上,您可以使用名为
x_local
的变量重写所有
func_B
,它的工作原理相同

顺序仅在函数执行更改全局x值的操作的顺序时起作用。因此,在我们的示例中,顺序并不重要,因为
func\u B
调用
func\u 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_locally
access_only
之间的区别--
access_only
在不调用
global
的情况下访问全局x,即使
create_locally
也不使用
global
,它也会创建一个本地副本,因为它正在赋值


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

这里有一个例子让我很吃惊,使用全局变量作为参数的默认值

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。惊喜Python2.7在第一次解析函数func时计算了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

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

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

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

这种措辞是不幸的。在Python中,分配给变量的值是一个引用,因此它在技术上是正确的(我毫不怀疑你的意思),但许多读者可能会将“改变值”解释为“改变对象”,事实并非如此--
xs.append(xs.pop(0))
在没有
global xs
@delnan的情况下工作得很好,我的答案措辞很谨慎,但我要澄清的是,在我给出的代码中,func_B是否做了(1)到x的全局副本(从func_A获得),(2)到与func_A的结果值相同的局部变量x,或者(3)到没有值且(在编译器看来)与“某个值”没有关系的局部变量x或者func_A中的x?
x
func_B中的x是一个局部变量,它从调用
func_A
的返回值中获取其值-因此我猜这将使它成为您的(2)好吧,假设x是func_A生成的某种随机序列(即,该func_A每次运行时生成不同的x)按编写的方式运行程序会使func_b修改不同于调用func_a时最初生成的x吗?如果是,我如何修复它?是的,如果
func_A
在每次运行期间更改全局变量并将其返回到
func_B
以使用,则
func_B
每次都将使用更改的值。我不确定你的“如何修复它”。你可能想接受对你当前的问题的最有帮助的答案,然后考虑打开一个关于后续问题的不同的问题。实际上这取决于X是什么。如果x是不可变的,则func_B中的x将保留在其中,因为即使它们具有相同的值,它也是在本地声明的。这适用于元组、整数。。。例如,如果它是一个列表的实例,而您执行了
x.append(“…”)
,则是全局变量x发生了更改,因为局部变量引用了全局变量。我认为这在实践中并不十分混乱