このような混乱のため、最初からグローバル変数を使用しないようにする必要があることはわかっていますが、それらを使用する場合は、以下の方法を使用するのが有効な方法でしょうか。 (私は別の関数で作成された変数のグローバルコピーを呼び出そうとしています。)
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
は、func_a
が使用および変更するx
のグローバルコピーと同じ値を持っていますか?定義後に関数を呼び出すとき、順序は重要ですか?
単にグローバル変数にアクセスしたい場合は、単にその名前を使います。しかし、 change にするには global
キーワードを使う必要があります。
例えば。
global someVar
someVar = 55
これにより、グローバル変数の値が55に変更されます。それ以外の場合は、55をローカル変数に代入するだけです。
関数定義リストの順番は関係ありません(それらが何らかの方法で互いに参照しないと仮定して)、それらが呼ばれる順番は関係ありません。
Pythonスコープ内では、そのスコープ内でまだ宣言されていない変数への代入は、新しいローカル変数exceptを作成します。その変数は、グローバルスコープ変数をキーワード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_locally
とaccess_only
の違いに注意してください - access_only
はglobal
を呼び出さないにもかかわらずグローバルxにアクセスしています、そしてcreate_locally
はglobal
も使用していませんが、それはassigning valueなのでローカルコピーを作成します。
ここでの混乱は、なぜグローバル変数を使うべきではないのかということです。
他の人が述べたように、関数でグローバル変数を変更できるようにするには、関数で変数global
を宣言する必要があります。アクセスするだけの場合は、global
は必要ありません。
それについてもう少し詳しく説明すると、「変更」の意味は次のとおりです。re-bindを使用して別のオブジェクトを指すようにするには、名前を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
これは、グローバルをパラメータのデフォルト値として使用した場合の問題の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
関数内でグローバル変数に直接アクセスできます。そのグローバル変数の値を変更したい場合は、 "global variable_name"を使用してください。次の例を見てください。
var = 1
def global_var_change():
global var
var = "value changed"
global_var_change() #call the function for changes
print var
一般的に言って、これは良いプログラミング方法ではありません。名前空間のロジックを破ることによって、コードは理解したりデバッグしたりするのが難しくなります。
グローバル変数に割り当てられた値を変更したいときは、global
宣言を使わなければなりません。
グローバル変数から読み取るためにそれを必要としません。オブジェクト上のメソッドを呼び出しても(そのオブジェクト内のデータが変更されても)、そのオブジェクトを保持している変数の値は変更されません(リフレクティブマジックがない)。