プログラムで変数が定義されている場合、その変数にはスコープがあり、変数のスコープはそのスコープと呼ばれます。
定義された変数の場所に応じて、2つのタイプの変数があります。
各関数が実行されると、システムはその関数に「一時メモリスペース」を割り当て、すべてのローカル変数はこの一時メモリスペースに格納されます。関数が実行されると、このメモリスペースが解放され、これらのローカル変数は無効になります。したがって、関数を終了した後、ローカル変数にアクセスできなくなります。
グローバル変数は、すべての関数でアクセスできることを意味します。
関数のローカルスコープ内であろうとグローバルスコープ内であろうと、複数の変数が存在する可能性があり、各変数は変数の値を「保持」します。この観点から、ローカルスコープであろうとグローバルスコープであろうと、これらの変数とその値は「見えない」辞書のようなものであり、変数名は辞書のキーであり、変数値は辞書の値です。
実際、Pythonは、指定された範囲の「変数辞書」を取得するために、次の3つのユーティリティ関数を提供します。
globals():この関数は、グローバルスコープ内のすべての変数で構成される「変数ディクショナリ」を返します。
locals():この関数は、現在のローカルスコープ内のすべての変数で構成される「変数ディクショナリ」を返します。
vars(object):指定されたオブジェクト範囲内のすべての変数で構成される「変数ディクショナリ」を取得します。オブジェクトパラメータが渡されない場合、vars()とlocals()はまったく同じ効果があります。
globals()とlocals()は完全に異なっているように見えますが、実際には関連しています。これら2つの関数の違いと接続については、おおよそ2つのポイントがあります。
locals()は常に、現在のローカルスコープ内のすべての変数で構成される「変数ディクショナリ」を取得します。したがって、グローバルスコープ内(関数外)でlocals()関数を呼び出すと、グローバルスコープ内のすべての変数で構成される「変数」も取得されます。 Dictionary ";およびglobals()は、実行場所に関係なく、グローバルスコープ内のすべての変数で構成される「変数ディクショナリ」を常に取得します。
一般的に、locals()とglobals()を使用して取得した「変数ディクショナリ」は、アクセスする必要があり、変更しないでください。しかし実際には、globals()またはlocals()を使用してグローバルスコープの「変数ディクショナリ」を取得するかどうかに関係なく、変更できます。この変更により、グローバル変数自体が実際に変更されます。ただし、locals()を介して取得されるローカルは変更されます。スコープ内の「変数ディクショナリ」は、変更されてもローカル変数には影響しません。
次のプログラムは、locals()関数とglobals()関数を使用して、ローカルスコープとグローバルスコープの「変数ディクショナリ」にアクセスする方法を示しています。
def test():
age =20
# 年齢ローカル変数への直接アクセス
print(age) #出力20
# 関数のローカルスコープの「変数配列」にアクセスします
print(locals()) # {'age':20}
# 関数のローカルスコープの「変数配列」を介して年齢変数にアクセスします
print(locals()['age']) # 20
# locals関数のローカルスコープの「変数配列」を介して年齢変数の値を変更します
locals()['age']=12
# 年齢変数の値に再度アクセスします
print('xxx', age) #まだ出力20
# グローバル関数を使用してx個のグローバル変数を変更します
globals()['x']=19
x =5
y =20print(globals()) # {...,'x':5,'y':20}
# グローバルアクセスでlocals関数を使用して、グローバル変数の「変数配列」にアクセスします
print(locals()) # {...,'x':5,'y':20}
# x個のグローバル変数への直接アクセス
print(x) # 5
# グローバル変数の「変数配列」を介してx個のグローバル変数にアクセスする
print(globals()['x']) # 5
# グローバル変数の「変数配列」を介してx個のグローバル変数に値を割り当てます
globals()['x']=39print(x) #出力39
# locals関数を使用して、グローバルスコープ内のx個のグローバル変数に値を割り当てます
locals()['x']=99print(x) #出力99
上記のプログラムから、locals()関数を使用して特定のスコープ内のすべての変数で構成される「変数辞書」にアクセスし、globals()関数を使用してグローバルスコープ内のグローバル変数で構成される「変数辞書」にアクセスすることがはっきりとわかります。 。
デフォルトでは、すべての関数でグローバル変数にアクセスできますが、グローバル変数と同じ名前の変数が関数で定義されている場合、ローカル変数はグローバル変数を非表示にします。たとえば、次のプログラム:
name ='Charlie'
def test():
# 名前グローバル変数への直接アクセス
print(name) # Charlie
test()print(name)
上記のプログラムでは、4行目が許可されているname変数に直接アクセスしており、この時点でプログラムはCharlieを出力します。この後に次のコード行を追加すると、次のようになります。
name ='モンキーキング'
プログラムを再度実行すると、次のエラーが表示されます。
UnboundLocalError : local variable ‘name' referenced before assignment
このエラーは、太字のコードによってアクセスされる名前変数が定義されていないことを示しています。これの理由は何ですか?これは、プログラムがtest()関数にコード「name = 'SunWukong'」の行を追加するためです。
Python構文では、関数内に存在しない変数に値を割り当てる場合、デフォルトでは新しいローカル変数を再定義することが規定されています。したがって、このコード行は、nameローカル変数を再定義することと同じであり、nameグローバル変数がマスクされるため、プログラムはエラーを報告します。
この問題を回避するには、次の2つの方法で上記のプログラムを変更できます。
隠されたグローバル変数へのアクセス。プログラムが引き続きnameグローバル変数にアクセスできるようにし、関数でnameローカル変数を再定義できる場合、つまり、関数でマスクされたグローバル変数にアクセスできる場合は、globals()関数を使用してこれを実現し、上記のプログラムを次のように変更できます。次の形式で十分です。
name ='Charlie'
def test():
# 名前グローバル変数への直接アクセス
print(globals()['name']) # Charlie
name ='モンキーキング'test()print(name) # Charlie
関数でグローバル変数を宣言します。関数内のグローバル変数に値を割り当てないようにするために(ローカル変数を再定義しないで)、グローバルステートメントを使用してグローバル変数を宣言できます。したがって、プログラムは次の形式に変更できます。
name ='Charlie'
def test():
# 名前がグローバル変数であることを宣言し、後続の割り当てステートメントはローカル変数を再定義しません
global name
# 名前グローバル変数への直接アクセス
print(name) # Charlie
name ='モンキーキング'test()print(name) # モンキーキング
「グローバル名」宣言を追加した後、プログラムは名前変数をグローバル変数として扱います。つまり、test()関数の後で名前に値を割り当てるステートメントは、ローカル変数を再定義するのではなく、グローバル変数にのみ値を割り当てます。
ナレッジポイントの拡張:
**python3 **の可変スコープ
**スコープ:**名前名が直接アクセスできるpythonプログラムのテキスト領域を指します。ここで、「直接アクセス可能」とは、次のことを意味します。名前への参照(修飾されていない)、名前名で名前を見つけようとします。
これまで、Python変数のスコープについてのこの記事を紹介しました。Python変数のスコープの詳細については、ZaLou.Cnの以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後、ZaLouをさらにサポートしていただければ幸いです。 Cn!
Recommended Posts