グローバル変数を関数内で作成または使用するにはどうすればよいですか?
ある関数でグローバル変数を作成した場合、そのグローバル変数を別の関数で使用するにはどうすればよいのでしょうか?グローバル変数にアクセスする必要がある関数のローカル変数に、グローバル変数を格納する必要がありますか?
グローバル変数に代入する各関数で global
と宣言することにより、他の関数でグローバル変数を使用することができます。
globvar = 0
def set_globvar_to_one():
global globvar # Needed to modify global copy of globvar
globvar = 1
def print_globvar():
print(globvar) # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar() # Prints 1
その理由は、グローバル変数はとても危険なので、Pythonは global
キーワードを明示的に要求することで、あなたが本当にそれを扱っていることを確認したいからだと想像しています。
モジュール間でグローバル変数を共有したい場合は、他の回答も参照してください。
私があなたの状況を正しく理解している場合、あなたが見ているのは、Pythonがローカル(機能)およびグローバル(モジュール)のネームスペースをどのように処理したかの結果です。
このようなモジュールがあるとします。
# sample.py
myGlobal = 5
def func1():
myGlobal = 42
def func2():
print myGlobal
func1()
func2()
これは42を印刷することを期待するかもしれませんが、代わりに5を印刷します。 すでに述べたように、「func1()」に「global」宣言を追加すると、「func2()」は42を出力します。
def func1():
global myGlobal
myGlobal = 42
ここで起こっていることは、Pythonは、明示的に別段の指示がない限り、関数内のどこにでも割り当てされている名前はその関数のローカルであると想定していることです。 名前から読み取りするだけで、名前がローカルに存在しない場合は、含まれているスコープで名前を検索しようとします(例:. モジュールのグローバルスコープ)。
したがって、42を「myGlobal」という名前に割り当てると、Pythonは同じ名前のグローバル変数を隠すローカル変数を作成します。 そのローカルは範囲外になり、「func1()」が戻るとgarbage-collectedになります。一方、「func2()」は(変更されていない)グローバル名以外を見ることはできません。 この名前空間の決定はコンパイル時に行われることに注意してください。, ランタイムではありません-「func1」内の「myGlobal」の値を読み取る場合。(割り当てる前に。, you'。;d
UnboundLocalError`を取得します。, Pythonはローカル変数である必要があると既に決定していますが、まだ関連付けられている値はありません。 ただし、「グローバル」ステートメントを使用することで、ローカルに割り当てるのではなく、他の場所で名前を探す必要があることをPythonに伝えます。
この動作は、ローカルネームスペースの最適化によって主に発生したと思います-この動作はありません。, Python'。;s VMは、関数内に新しい名前が割り当てられるたびに、少なくとも3つの名前検索を実行する必要があります。 (名前が確実に'になったことを確認するため。;tはすでにモジュール/ビルトインレベルで存在しています。) これは、非常に一般的な操作を大幅に遅くします。)。
名前空間]1の概念を探求したいと思うかもしれません。Pythonでは、モジュールはグローバルなデータのための自然な場所です。
各モジュールはそれ自身のプライベートなシンボルテーブルを持ち、それはそのモジュールで定義されたすべての関数によってグローバルシンボルテーブルとして使用されます。したがって、モジュールの作者は、ユーザのグローバル変数と偶然に衝突することを心配することなく、モジュール内のグローバル変数を使用することができます。一方、自分が何をしているかを知っていれば、モジュールの関数を参照するために使われるのと同じ記法、 modname.itemname
でモジュールのグローバル変数に触れることができます。
global-in-a-module の具体的な使い方は、ここ - How do I share global variables across modules? で説明しています。
一つのプログラムの中でモジュール間で情報を共有する標準的な方法は、特別な設定モジュール(しばしば config または cfg と呼ばれます)を作成することです。アプリケーションのすべてのモジュールで、この設定モジュールをインポートしてください。各モジュールのインスタンスは1つだけなので、モジュールオブジェクトに加えられたすべての変更は、どこでも反映されます。例えば
ファイル: config.py
x = 0 # コンフィギュレーション設定 'x' のデフォルト値
ファイル: mod.py
インポートconfig config.x = 1
ファイル: main.py ファイル名:main.py インポートコンフィグ インポートMOD print config.x
Pythonは単純なヒューリスティックを使用して、ローカルとグローバルの間で、変数をロードするスコープを決定します。 変数の名前が割り当ての左側に表示され、グローバルと宣言されていない場合、ローカルと見なされます。 課題の左側に表示されない場合、グローバルと見なされます。
>>> import dis
>>> def foo():
... global bar
... baz = 5
... print bar
... print baz
... print quux
...
>>> dis.disassemble(foo.func_code)
3 0 LOAD_CONST 1 (5)
3 STORE_FAST 0 (baz)
4 6 LOAD_GLOBAL 0 (bar)
9 PRINT_ITEM
10 PRINT_NEWLINE
5 11 LOAD_FAST 0 (baz)
14 PRINT_ITEM
15 PRINT_NEWLINE
6 16 LOAD_GLOBAL 1 (quux)
19 PRINT_ITEM
20 PRINT_NEWLINE
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
>>>
foo()
の割り当ての左側に表示されるbazが唯一の LOAD_FAST
変数である方法を参照してください。
関数内でグローバル変数を参照したい場合、どの変数がグローバルであるかを宣言するために global キーワードを使用することができます。すべての場合に使う必要はありません(ここの誰かが間違って主張していますが)。式で参照される名前がローカルスコープやこの関数が定義されている関数内のスコープで見つからない場合、グローバル変数の中から探されます。
しかし、関数内でグローバル変数として宣言されていない新しい変数に代入すると、暗黙のうちにローカル変数として宣言され、既存の同名のグローバル変数を覆い隠してしまうことがあるのです。
また、グローバル変数は便利ですが、そうではないと主張する一部のOOP狂には反対です。特に小規模なスクリプトでは、OOPは過剰なのです。
既存の回答に加えて、これをより混乱させる:
Pythonでは、関数内でのみ参照される変数はです。 暗黙的にグローバル。 変数がどこかに新しい値を割り当てられている場合。 関数の本文内では、 local と見なされます。 変数の場合。 関数内に新しい値が割り当てられると、変数は割り当てられます。 暗黙的にローカルであり、明示的に「グローバル」として宣言する必要があります。 。 最初は少し意外ですが、一瞬の考察が説明します。 この。 一方では、割り当てられた変数のグローバルを要求すると、aが提供されます。 意図しない副作用に対するバー。 一方、グローバルだった場合。 すべてのグローバル参照に必要な場合は、グローバル全体を使用します。 時間。 ビルトインへのすべての参照をグローバルとして宣言する必要があります。 関数またはインポートされたモジュールのコンポーネントに。 この乱雑さはそうするでしょう。 識別のためのグローバル宣言の有用性を打ち破ります。 副作用。
ある関数でグローバル変数を作成する場合、その変数を別の関数で使用するにはどうすればよいですか?
次の機能でグローバルを作成できます。
def create_global_variable():
global global_variable # must declare it to be a global first
# modifications are thus reflected on the module's global scope
global_variable = 'Foo'
関数を作成しても、実際にはコードが実行されません。 したがって、「create_global_variable」関数を呼び出します。
>>> create_global_variable()
次のオブジェクトを変更することを期待しない限り、それを使用できます。
例えば、。
def use_global_variable():
return global_variable + '!!!'
これで、グローバル変数を使用できます。
>>> use_global_variable()
'Foo!!!'
グローバル変数を別のオブジェクトにポイントするには、グローバルキーワードを再度使用する必要があります。
def change_global_variable():
global global_variable
global_variable = 'Bar'
この関数を作成した後でも、実際に変更したコードはまだ実行されていません。
>>> use_global_variable()
'Foo!!!'
したがって、関数を呼び出した後:
>>> change_global_variable()
グローバル変数が変更されたことがわかります。 global_variable
の名前は 'Bar'
を指すようになりました:
>>> use_global_variable()
'Bar!!!'
Pythonの「グローバル」は真にグローバルではないことに注意してください。モジュールレベルまでグローバルです。 したがって、グローバルであるモジュールに記述された関数でのみ使用できます。 関数は、それらが記述されているモジュールを記憶するため、他のモジュールにエクスポートされるときでも、グローバル変数を見つけるために作成されたモジュールを調べます。
同じ名前のローカル変数を作成すると、グローバル変数:が影になります。
def use_local_with_same_name_as_global():
# bad name for a local variable, though.
global_variable = 'Baz'
return global_variable + '!!!'
>>> use_local_with_same_name_as_global()
'Baz!!!'
ただし、その誤った名前のローカル変数を使用しても、グローバル変数は変わりません。
>>> use_global_variable()
'Bar!!!'
何をしているのかを正確に把握し、そのための非常に正当な理由がない限り、グローバルと同じ名前のローカル変数を使用することは避けてください。 まだそんな理由には出ていません。
並列実行では、何が起こっているのか理解できない場合、グローバル変数が予期しない結果を引き起こす可能性があります。 マルチプロセッシング内でグローバル変数を使用する例を次に示します。 各プロセスが変数の独自のコピーで機能することを明確に確認できます。
import multiprocessing
import os
import random
import sys
import time
def worker(new_value):
old_value = get_value()
set_value(random.randint(1, 99))
print('pid=[{pid}] '
'old_value=[{old_value:2}] '
'new_value=[{new_value:2}] '
'get_value=[{get_value:2}]'.format(
pid=str(os.getpid()),
old_value=old_value,
new_value=new_value,
get_value=get_value()))
def get_value():
global global_variable
return global_variable
def set_value(new_value):
global global_variable
global_variable = new_value
global_variable = -1
print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after set_value(), get_value() = [%s]' % get_value())
processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))
出力:。
before set_value(), get_value() = [-1]
after set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]
結局のところ、答えは常に簡単です。
これは、「メイン」の定義でそれを表示する簡単な方法を持つ小さなサンプルモジュールです。
def five(enterAnumber,sumation):
global helper
helper = enterAnumber + sumation
def isTheNumber():
return helper
「メイン」の定義でそれを表示する方法は次のとおりです。
import TestPy
def main():
atest = TestPy
atest.five(5,8)
print(atest.isTheNumber())
if __name__ == '__main__':
main()
この単純なコードはそのように機能し、実行されます。 それが役に立てば幸いです。
使用するすべての関数でグローバル変数を参照する必要があります。
次のように:
var = "test"
def printGlobalText():
global var #wWe are telling to explicitly use the global version
var = "global from printGlobalText fun."
print "var from printGlobalText: " + var
def printLocalText():
#We are NOT telling to explicitly use the global version, so we are creating a local variable
var = "local version from printLocalText fun"
print "var from printLocalText: " + var
printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""
実際には、グローバルをローカル変数に格納するのではなく、元のグローバル参照が参照するのと同じオブジェクトへのローカル参照を作成するだけです。 Pythonのほとんどすべてのものはオブジェクトを参照する名前であり、通常の操作では何もコピーされないことに注意してください。
識別子が事前定義されたグローバルを参照する時期を明示的に指定する必要がなかった場合は、おそらく識別子が新しいローカル変数であるかどうかを明示的に指定する必要があります(たとえば、「var」コマンドなど) JavaScriptで見られます)。 ローカル変数は、深刻で非重要なシステムではグローバル変数よりも一般的であるため、Pythonのシステムはほとんどの場合より理にかなっています。
グローバル変数が存在する場合はそれを使用し、存在しない場合はローカル変数を作成して、推測を試みた言語を使用することができます。 ただし、それは非常にエラーが発生しやすいでしょう。 たとえば、別のモジュールをインポートすると、その名前のグローバル変数が誤って導入され、プログラムの動作が変わる可能性があります。
これを試して:
def x1():
global x
x = 6
def x2():
global x
x = x+1
print x
x = 5
x1()
x2() # output --> 7
オンとアドオンに続いて、ファイルを使用して、すべてローカルに宣言されたすべてのグローバル変数を含み、次に「としてインポート」します。
ファイル initval.py :
Stocksin = 300
Prices = []
ファイル getstocks.py :
import initval as iv
def getmystocks():
iv.Stocksin = getstockcount()
def getmycharts():
for ic in range(iv.Stocksin):
グローバル配列の明示的な要素に書き込むことは、明らかにグローバル宣言を必要としませんが、「卸売」に書き込むには次の要件があります。
import numpy as np
hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])
def func1():
global hostValue # mandatory, else local.
hostValue = 2.0
def func2():
global hostValue # mandatory, else UnboundLocalError.
hostValue += 1.0
def func3():
global hostArray # mandatory, else local.
hostArray = np.array([14., 15.])
def func4(): # no need for globals
hostArray[0] = 123.4
def func5(): # no need for globals
hostArray[1] += 1.0
def func6(): # no need for globals
hostMatrix[1][1] = 12.
def func7(): # no need for globals
hostMatrix[0][0] += 0.33
func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix
他の回答では見たことがないので、これを追加します。これは、同様のことに苦労している人にとって役立つ場合があります。 globals()
関数は、変更可能なグローバルシンボルディクショナリを返します。ここで、残りのコードでデータを「魔法のように」利用できるようにできます。 。
例:
from pickle import load
def loaditem(name):
with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
globals()[name] = load(openfile)
return True
と。
from pickle import dump
def dumpfile(name):
with open(name+".dat", "wb") as outfile:
dump(globals()[name], outfile)
return True
変数をグローバル名前空間からグローバル名前空間にダンプ/ロードするだけです。 超便利、大騒ぎ、大騒ぎなし。 Python 3のみであることを確認してください。
変更を表示するクラス名空間を参照します。
この例では、ランナーはファイル構成の max を使用しています。 ランナーが使用しているときに、テストで max の値を変更してほしい。
main / config.py 。
max = 15000
main / runner.py 。
from main import config
def check_threads():
return max < thread_count
tests / runner_test.py 。
from main import runner # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
def test_threads(self):
runner.max = 0 # <----- 2. set global
check_threads()