重複の可能性:
グローバル変数を作成した関数以外の関数でグローバル変数を使用する
プログラムが混乱しないように関数を使用していますが、ローカル変数をグローバルにする方法がわかりません。
重複の可能性:
グローバル変数を作成した関数以外の関数でグローバル変数を使用する
プログラムが混乱しないように関数を使用していますが、ローカル変数をグローバルにする方法がわかりません。
同じことを実現するための2つの方法を次に示します。
パラメータとリターンの使用(推奨)
def other_function(parameter):
return parameter + 5
def main_function():
x = 10
print(x)
x = other_function(x)
print(x)
を実行するmain_function
と、次の出力が得られます
>>> 10
>>> 15
グローバルの使用(これは絶対に行わないでください)
x = 0 # The initial value of x, with global scope
def other_function():
global x
x = x + 5
def main_function():
print(x) # Just printing - no need to declare global yet
global x # So we can change the global x
x = 10
print(x)
other_function()
print(x)
今、あなたは得るでしょう:
>>> 0 # Initial global value
>>> 10 # Now we've set it to 10 in `main_function()`
>>> 15 # Now we've added 5 in `other_function()`
関数の外で変数を宣言するだけです。
globalValue = 1
def f(x):
print(globalValue + x)
関数内からグローバルに割り当てる必要がある場合は、次のglobal
ステートメントを使用します。
def f(x):
global globalValue
print(globalValue + x)
globalValue += 1
関数の内部状態にアクセスする必要がある場合は、クラスを使用する方がよいでしょう。クラスインスタンスを呼び出し可能にすることで、クラスインスタンスを関数のように動作させることができます。これは、次のように定義することで実行され__call__
ます。
class StatefulFunction( object ):
def __init__( self ):
self.public_value = 'foo'
def __call__( self ):
return self.public_value
>> f = StatefulFunction()
>> f()
`foo`
>> f.public_value = 'bar'
>> f()
`bar`
グローバルを使用すると、プログラムが混乱することにもなります。グローバルを回避するように一生懸命努力することをお勧めします。とはいえ、「グローバル」はPythonのキーワードであるため、次のように特定の変数をグローバルとして指定できます。
def foo():
global bar
bar = 32
「global」キーワードが使用されることは非常にまれであるため、デザインを再考することを真剣に提案します。
モジュールスコープを使用できます。あなたがというモジュールを持っているとしましょうutils
:
f_value = 'foo'
def f():
return f_value
f_value
は、それをインポートする他のモジュールによって変更できるモジュール属性です。モジュールはシングルトンであるためutils
、1つのモジュールからの変更は、インポートされた他のすべてのモジュールからアクセスできます。
>> import utils
>> utils.f()
'foo'
>> utils.f_value = 'bar'
>> utils.f()
'bar'
関数は名前でインポートできることに注意してください。
>> import utils
>> from utils import f
>> utils.f_value = 'bar'
>> f()
'bar'
しかし、属性ではありません:
>> from utils import f, f_value
>> f_value = 'bar'
>> f()
'foo'
これは、モジュール属性によって参照されるオブジェクトf_value
にローカルスコープのようにラベルを付けているがbar
、関数f
がモジュール属性を参照している間に、オブジェクトを文字列に再バインドしているためです。