330

このような混乱のため、そもそもグローバル変数の使用を避けるべきであることはわかっていますが、使用する場合、次のように使用することは有効ですか? (別の関数で作成された変数のグローバル コピーを呼び出そうとしています。)

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

2 番目の関数が使用する は、使用および変更するxのグローバル コピーと同じ値を持っていますか? 定義後に関数を呼び出す場合、順序は重要ですか?xfunc_a

4

6 に答える 6

489

単にグローバル変数にアクセスしたい場合は、その名前を使用します。ただし、その値を変更globalするには、キーワードを使用する必要があります。

例えば

global someVar
someVar = 55

これにより、グローバル変数の値が55に変更されます。それ以外の場合は、55がローカル変数に割り当てられます。

関数定義リストの順序は重要ではありません(何らかの方法で相互に参照していないと仮定すると)、呼び出される順序は重要です。

于 2012-05-14T17:38:03.323 に答える
131

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実際、名前付きの変数ですべてを書き換えることができ、x_local同じように機能します。

順序は、関数がグローバル x の値を変更する操作を実行する順序に関してのみ重要です。func_Bしたがって、この例では、を呼び出すため、順序は重要ではありません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を呼び出していないにもかかわらずグローバル x にアクセスしていることglobalに注意してください。どちらcreate_locallyも使用していませんが、値を割り当てglobalているため、ローカル コピーが作成されます。

ここでの混乱は、グローバル変数を使用してはならない理由です。

于 2012-05-14T18:03:33.437 に答える
23

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
于 2012-05-14T17:52:52.023 に答える
9

これは、パラメーターのデフォルト値としてグローバルを使用して、私を捕まえた 1 つのケースです。

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 であると予想していましたが、驚きました。Python 2.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
于 2016-06-01T15:16:35.087 に答える
2

globalグローバル変数に割り当てられた値を変更する場合は、宣言を使用する必要があります。

グローバル変数から読み取るために必要ありません。オブジェクトのメソッドを呼び出しても(そのオブジェクト内のデータが変更されたとしても)、そのオブジェクトを保持している変数の値は変更されないことに注意してください(反射魔法はありません)。

于 2012-05-14T17:38:45.160 に答える