Arasındaki fark nedir globals(), locals()ve vars()? Ne geri dönüyorlar? Sonuçlara ilişkin güncellemeler faydalı mı?
Arasındaki fark nedir globals(), locals()ve vars()? Ne geri dönüyorlar? Sonuçlara ilişkin güncellemeler faydalı mı?
Yanıtlar:
Bunların her biri bir sözlük döndürür:
globals() her zaman modül ad alanının sözlüğünü döndürürlocals() Her zaman döndüren bir sözlüğünü akım advars()döner ya bir (hayır seçeneği ile çağrılmış ise) Geçerli isim veya sözlüğü Tartışmanın Sözlük.localsve varsbiraz daha açıklama yapabilir. Eğer locals()bir işlev içinde denir, o ana ve getiri bunun itibarıyla geçerli yerel değişken ad değerleri (artı herhangi kapatma değişkenler) ile bir dicti günceller. locals()Aynı yığın çerçevesinde birden çok çağrı her seferinde aynı dikdörtgeni döndürür - yığın çerçevesi nesnesine f_localsözniteliği olarak eklenir . Dikt içeriği her locals()aramada ve her f_localsözellik erişiminde güncellenir , ancak yalnızca bu aramalarda veya özellik erişimlerinde. Değişkenler atandığında otomatik olarak güncellenmez ve dikte girişlerinin atanması karşılık gelen yerel değişkenleri atamaz:
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()
bize verir:
{'x': 1}
{'x': 1, 'l': {...}}
2 1
2 3
2 2
İlki print(l)yalnızca bir 'x'girişi gösterir , çünkü atama çağrıdan lsonra gerçekleşir locals(). İkincisi print(l), locals()tekrar aradıktan sonra l, dönüş değerini kaydetmemize rağmen bir giriş gösterir . Üçüncü ve dördüncü prints değişkenleri atamanın güncellenmediğini lve tersini gösterir, ancak eriştikten sonra f_localsyerel değişkenler locals()tekrar kopyalanır .
İki not:
exec "pass", bu işleve bir çizgi koyarak bu işi yapmak mümkündür . Bu, işlevi locals()yerel değişkenlerin kanonik temsili olarak dikte kullanan daha eski, daha yavaş bir yürütme moduna geçirir.Eğer locals()denir dışında bir fonksiyonu mevcut ad alanıdır fiili sözlüğü döndürür. Ad ilave değişiklikler vardır sözlükte yansıyan ve sözlüğe değişiklikler vardır ad yansıyan:
class Test(object):
a = 'one'
b = 'two'
huh = locals()
c = 'three'
huh['d'] = 'four'
print huh
bize verir:
{
'a': 'one',
'b': 'two',
'c': 'three',
'd': 'four',
'huh': {...},
'__module__': '__main__',
}
Şimdiye kadar, söylediğim her şey locals()için de doğru vars()... işte fark: vars()tek bir nesneyi argümanı olarak kabul eder ve ona bir nesne verirseniz __dict__, o nesnenin değerini döndürür . Tipik bir nesne için, __dict__öznitelik verilerinin çoğunun saklandığı yerdir. Sınıf değişkenleri ve modül globalleri buna dahildir:
class Test(object):
a = 'one'
b = 'two'
def frobber(self):
print self.c
t = Test()
huh = vars(t)
huh['c'] = 'three'
t.frobber()
bu da bize:
three
Bir işlevin __dict__yerel değişkenler değil, öznitelik ad alanı olduğunu unutmayın . Bir işlevin __dict__yerel değişkenleri depolaması mantıklı olmaz , çünkü özyineleme ve çoklu iş parçacığı aynı anda bir işleve birden fazla çağrı olabileceği anlamına gelir, her birinin kendi yerel ayarı vardır:
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)
bu da bize:
Inner call locals: {'outer': False}
f.__dict__: {'x': 3}
Outer call locals: {'outer': True}
f.__dict__: {'x': 3}
Burada fkendini yinelemeli olarak çağırır, böylece iç ve dış çağrılar çakışır. Her biri çağrı yaparken kendi yerel değişkenlerini görür locals(), ancak her iki çağrı da aynı görür f.__dict__ve f.__dict__içinde yerel değişkenler yoktur.
vars()veya locals()sözlüğe eklenen değişkenlere erişebilirsiniz eval(). EG: yürütüldüğünde def test(): huh = locals(); huh['d'] = 4; print eval('d')4 yazdırır test()!
dict(tarafından döndürülen locals()) ataması yerel ad alanına yansıtılır ve yerel ad alanında yapılan değişiklikler dict(pitonumda) yansıtılır . Tek şey, spesifikasyonun bu davranışı garanti etmemesidir.
import thisve Google'dasite:docs.python.org namespace