dapatkah seseorang memperbarui semua ini dengan python 3 dan membuat skrip benar-benar berfungsi?
Charlie Parker
Jawaban:
172
Masing-masing mengembalikan kamus:
globals()selalu mengembalikan kamus namespace modul
locals()selalu mengembalikan sebuah kamus dari saat namespace
vars()kembali baik kamus namespace saat ini (jika disebut dengan tidak ada argumen) atau yang kamus argumen.
localsdan varsbisa menggunakan penjelasan lebih lanjut. Jika locals()dipanggil di dalam suatu fungsi, ia akan memperbarui dict dengan nilai-nilai namespace variabel lokal saat ini (ditambah variabel penutupan apa pun) pada saat itu dan mengembalikannya. Beberapa panggilan ke locals()dalam bingkai tumpukan yang sama mengembalikan dict yang sama setiap kali - itu dilampirkan ke objek bingkai tumpukan sebagai f_localsatributnya. Konten dikt diperbarui pada setiap locals()panggilan dan setiap f_localsakses atribut, tetapi hanya pada panggilan atau akses atribut tersebut. Itu tidak secara otomatis memperbarui ketika variabel ditugaskan, dan menugaskan entri dalam dikt tidak akan menetapkan variabel lokal yang sesuai:
import inspect
def f():
x =1
l = locals()print(l)
locals()print(l)
x =2print(x, l['x'])
l['x']=3print(x, l['x'])
inspect.currentframe().f_locals
print(x, l['x'])
f()
memberi kita:
{'x':1}{'x':1,'l':{...}}212322
Yang pertama print(l)hanya menunjukkan 'x'entri, karena penugasan lterjadi setelah locals()panggilan. Yang kedua print(l), setelah menelepon locals()lagi, menunjukkan lentri, meskipun kami tidak menyimpan nilai pengembalian. Yang ketiga dan keempat printmenunjukkan bahwa menugaskan variabel tidak memperbarui ldan sebaliknya, tetapi setelah kita mengakses f_locals, variabel lokal disalin locals()lagi.
Dua catatan:
Perilaku ini khusus untuk CPython - Python lain mungkin mengizinkan pembaruan untuk membuatnya kembali ke namespace lokal secara otomatis.
Dalam CPython 2.x dimungkinkan untuk membuat pekerjaan ini dengan meletakkan exec "pass"garis di fungsi. Ini mengalihkan fungsi ke mode eksekusi yang lebih lama dan lebih lambat yang menggunakan locals()dict sebagai representasi kanonik variabel lokal.
Jika locals()dipanggil di luar fungsi, ia mengembalikan kamus aktual yang merupakan namespace saat ini. Perubahan selanjutnya ke namespace yang tercermin dalam kamus, dan perubahan kamus yang tercermin dalam namespace:
classTest(object):
a ='one'
b ='two'
huh = locals()
c ='three'
huh['d']='four'print huh
Sejauh ini, semua yang saya katakan tentang locals()itu juga berlaku untuk vars()... inilah bedanya: vars()menerima satu objek sebagai argumennya, dan jika Anda memberikannya objek, ia mengembalikan __dict__objek itu. Untuk objek tipikal, ini __dict__adalah tempat sebagian besar data atributnya disimpan. Ini termasuk variabel kelas dan modul global:
classTest(object):
a ='one'
b ='two'def frobber(self):print self.c
t =Test()
huh = vars(t)
huh['c']='three'
t.frobber()
yang memberi kita:
three
Perhatikan bahwa fungsi __dict__adalah namespace atributnya, bukan variabel lokal. Tidak masuk akal jika suatu fungsi __dict__menyimpan variabel lokal, karena rekursi dan multithreading berarti ada beberapa panggilan ke suatu fungsi pada saat bersamaan, masing-masing dengan penduduk lokal mereka sendiri:
Di sini, fpanggilan itu sendiri secara rekursif, sehingga panggilan dalam dan luar tumpang tindih. Masing-masing melihat variabel lokal sendiri ketika panggilan locals(), tetapi kedua panggilan melihat hal yang sama f.__dict__, dan f.__dict__tidak memiliki variabel lokal di dalamnya.
Bagian "dan setiap tugas ke kamus tidak tercermin dalam namespace lokal yang sebenarnya" mungkin akan sedikit diucapkan .
Sven Marnach
Anehnya, Anda dapat mengakses variabel yang ditambahkan ke vars()atau locals()kamus yang disebut dalam suatu fungsi jika Anda menggunakannya eval(). EG: def test(): huh = locals(); huh['d'] = 4; print eval('d')mencetak 4 saat test()dieksekusi!
Mark Mikofski
1
Sebenarnya penugasan ke dict(dikembalikan oleh locals()) kebetulan tercermin di namespace lokal dan perubahan ke namespace lokal kebetulan tercermin dalam dict(dalam python saya). Satu-satunya hal adalah spesifikasi tidak menjamin perilaku ini.
menjulang tinggi
Penggunaan istilah lingkup nama terlihat lebih mudah bagi saya daripada namespace .
overexchange
1
@overexchange: import thisdan di googlesite:docs.python.org namespace
Jawaban:
Masing-masing mengembalikan kamus:
globals()
selalu mengembalikan kamus namespace modullocals()
selalu mengembalikan sebuah kamus dari saat namespacevars()
kembali baik kamus namespace saat ini (jika disebut dengan tidak ada argumen) atau yang kamus argumen.locals
danvars
bisa menggunakan penjelasan lebih lanjut. Jikalocals()
dipanggil di dalam suatu fungsi, ia akan memperbarui dict dengan nilai-nilai namespace variabel lokal saat ini (ditambah variabel penutupan apa pun) pada saat itu dan mengembalikannya. Beberapa panggilan kelocals()
dalam bingkai tumpukan yang sama mengembalikan dict yang sama setiap kali - itu dilampirkan ke objek bingkai tumpukan sebagaif_locals
atributnya. Konten dikt diperbarui pada setiaplocals()
panggilan dan setiapf_locals
akses atribut, tetapi hanya pada panggilan atau akses atribut tersebut. Itu tidak secara otomatis memperbarui ketika variabel ditugaskan, dan menugaskan entri dalam dikt tidak akan menetapkan variabel lokal yang sesuai:memberi kita:
Yang pertama
print(l)
hanya menunjukkan'x'
entri, karena penugasanl
terjadi setelahlocals()
panggilan. Yang keduaprint(l)
, setelah meneleponlocals()
lagi, menunjukkanl
entri, meskipun kami tidak menyimpan nilai pengembalian. Yang ketiga dan keempatprint
menunjukkan bahwa menugaskan variabel tidak memperbaruil
dan sebaliknya, tetapi setelah kita mengaksesf_locals
, variabel lokal disalinlocals()
lagi.Dua catatan:
exec "pass"
garis di fungsi. Ini mengalihkan fungsi ke mode eksekusi yang lebih lama dan lebih lambat yang menggunakanlocals()
dict sebagai representasi kanonik variabel lokal.Jika
locals()
dipanggil di luar fungsi, ia mengembalikan kamus aktual yang merupakan namespace saat ini. Perubahan selanjutnya ke namespace yang tercermin dalam kamus, dan perubahan kamus yang tercermin dalam namespace:memberi kita:
Sejauh ini, semua yang saya katakan tentang
locals()
itu juga berlaku untukvars()
... inilah bedanya:vars()
menerima satu objek sebagai argumennya, dan jika Anda memberikannya objek, ia mengembalikan__dict__
objek itu. Untuk objek tipikal, ini__dict__
adalah tempat sebagian besar data atributnya disimpan. Ini termasuk variabel kelas dan modul global:yang memberi kita:
Perhatikan bahwa fungsi
__dict__
adalah namespace atributnya, bukan variabel lokal. Tidak masuk akal jika suatu fungsi__dict__
menyimpan variabel lokal, karena rekursi dan multithreading berarti ada beberapa panggilan ke suatu fungsi pada saat bersamaan, masing-masing dengan penduduk lokal mereka sendiri:yang memberi kita:
Di sini,
f
panggilan itu sendiri secara rekursif, sehingga panggilan dalam dan luar tumpang tindih. Masing-masing melihat variabel lokal sendiri ketika panggilanlocals()
, tetapi kedua panggilan melihat hal yang samaf.__dict__
, danf.__dict__
tidak memiliki variabel lokal di dalamnya.sumber
vars()
ataulocals()
kamus yang disebut dalam suatu fungsi jika Anda menggunakannyaeval()
. EG:def test(): huh = locals(); huh['d'] = 4; print eval('d')
mencetak 4 saattest()
dieksekusi!dict
(dikembalikan olehlocals()
) kebetulan tercermin di namespace lokal dan perubahan ke namespace lokal kebetulan tercermin dalamdict
(dalam python saya). Satu-satunya hal adalah spesifikasi tidak menjamin perilaku ini.import this
dan di googlesite:docs.python.org namespace