どのような違いがあるglobals()、locals()とvars()?彼らは何を返しますか?結果の更新は役に立ちますか?
どのような違いがあるglobals()、locals()とvars()?彼らは何を返しますか?結果の更新は役に立ちますか?
回答:
これらはそれぞれ辞書を返します:
globals() 常にモジュール名前空間の辞書を返しますlocals() 常に返すの辞書現在のネームスペースをvars()リターンのいずれか、現在のネームスペースの辞書(引数なしで呼び出された場合)、または、引数の辞書。localsそして、varsもう少し説明を使用できます。場合locals()関数の内部と呼ばれ、それが現在のローカル変数の名前空間の値(プラス任意のクロージャ変数)その瞬間のように戻り、それを持つ辞書を更新します。locals()同じスタックフレーム内で複数の呼び出しを行うと、毎回同じdictが返されf_localsます。属性としてスタックフレームオブジェクトにアタッチされます。辞書の内容は、各locals()呼び出しおよび各f_locals属性アクセスで更新されますが、そのような呼び出しまたは属性アクセスでのみ更新されます。変数が割り当てられても自動的には更新されません。また、dictにエントリを割り当てても、対応するローカル変数は割り当てられません。
import inspect
def f():
x = 1
l = locals()
print(l)
locals()
print(l)
x = 2
print(x, l['x'])
l['x'] = 3
print(x, l['x'])
inspect.currentframe().f_locals
print(x, l['x'])
f()
私たちに与える:
{'x': 1}
{'x': 1, 'l': {...}}
2 1
2 3
2 2
への割り当ては呼び出し後に行われるため、最初print(l)の'x'エントリはエントリのみを示しlていlocals()ます。2番目のはprint(l)、locals()再度呼び出した後l、戻り値を保存していませんが、エントリを示しています。3番目と4番目printのは、変数を割り当てても更新されずl、その逆も同様であることを示していますが、にアクセスするとf_locals、ローカル変数がlocals()再びコピーされます。
2つのメモ:
exec "pass"、関数に行を入れることでこれを機能させることができます。これは、関数をlocals()ローカル変数の正規表現としてdict を使用する、より古い、より遅い実行モードに切り替えます。関数の外locals()で呼び出された場合、現在の名前空間である実際の辞書を返します。名前空間へのさらなる変更がされている辞書に反映され、辞書に変更がされている名前空間に反映します。
class Test(object):
a = 'one'
b = 'two'
huh = locals()
c = 'three'
huh['d'] = 'four'
print huh
私たちに与える:
{
'a': 'one',
'b': 'two',
'c': 'three',
'd': 'four',
'huh': {...},
'__module__': '__main__',
}
これまでのところ、私が述べたことlocals()はすべて当てはまりますvars()...違いは次のとおりです。 vars()単一のオブジェクトを引数として受け入れ、オブジェクトを指定すると、そのオブジェクトのが返さ__dict__れます。典型的なオブジェクトの場合、オブジェクトの__dict__ほとんどの属性データが格納されています。これには、クラス変数とモジュールグローバルが含まれます。
class Test(object):
a = 'one'
b = 'two'
def frobber(self):
print self.c
t = Test()
huh = vars(t)
huh['c'] = 'three'
t.frobber()
それは私たちに与えます:
three
関数__dict__はローカル変数ではなく属性の名前空間であることに注意してください。関数が__dict__ローカル変数を格納することは意味がありません。再帰とマルチスレッドは、それぞれ独自のローカルを持つ関数への複数の呼び出しが同時に存在する可能性があるためです。
def f(outer):
if outer:
f(False)
print('Outer call locals:', locals())
print('f.__dict__:', f.__dict__)
else:
print('Inner call locals:', locals())
print('f.__dict__:', f.__dict__)
f.x = 3
f(True)
それは私たちに与えます:
Inner call locals: {'outer': False}
f.__dict__: {'x': 3}
Outer call locals: {'outer': True}
f.__dict__: {'x': 3}
ここでfは、それ自体を再帰的に呼び出しているため、内部呼び出しと外部呼び出しが重複しています。それが呼び出したときにそれぞれが独自のローカル変数を見ているlocals()が、両方の呼び出しは同じを見f.__dict__て、f.__dict__その中の任意のローカル変数を持っていません。
vars()またはlocals()関数内で呼び出された辞書にアクセスできますeval()。EG:が実行されるとdef test(): huh = locals(); huh['d'] = 4; print eval('d')4を出力しtest()ます!
dict(によって返されるlocals())への割り当ては、たまたまローカルネームスペースに反映され、ローカルネームスペースへの変更は、たまたまdict(私のPythonで)に反映されます。唯一のことは、仕様がこの動作を保証しないことです。
import thisand googlesite:docs.python.org namespace