Tidak ada jawaban menyeluruh tentang waktu Python3, jadi saya membuat jawaban di sini. Sebagian besar yang dijelaskan di sini dirinci dalam Resolusi 4.2.2 nama - nama dokumentasi Python 3.
Seperti yang diberikan dalam jawaban lain, ada 4 cakupan dasar, LEGB, untuk Lokal, Melampirkan, Global dan Builtin. Selain itu, ada ruang lingkup khusus, badan kelas , yang tidak mencakup ruang lingkup terlampir untuk metode yang didefinisikan dalam kelas; tugas apa pun dalam tubuh kelas membuat variabel dari sana terikat di tubuh kelas.
Terutama, tidak ada pernyataan blokir, selain def
dan class
, membuat ruang lingkup variabel. Dalam Python 2 daftar pemahaman tidak membuat lingkup variabel, namun dalam Python 3 variabel lingkaran dalam daftar daftar dibuat dalam lingkup baru.
Untuk menunjukkan kekhasan badan kelas
x = 0
class X(object):
y = x
x = x + 1 # x is now a variable
z = x
def method(self):
print(self.x) # -> 1
print(x) # -> 0, the global x
print(y) # -> NameError: global name 'y' is not defined
inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)
Jadi tidak seperti dalam fungsi body, Anda dapat menetapkan kembali variabel ke nama yang sama di kelas tubuh, untuk mendapatkan variabel kelas dengan nama yang sama; pencarian lebih lanjut pada nama ini diselesaikan ke variabel kelas sebagai gantinya.
Salah satu kejutan yang lebih besar bagi banyak pendatang baru di Python adalah for
loop tidak membuat lingkup variabel. Dalam Python 2, daftar pemahaman tidak membuat ruang lingkup baik (sementara generator dan pemahaman dikte lakukan!) Alih-alih mereka membocorkan nilai dalam fungsi atau lingkup global:
>>> [ i for i in range(5) ]
>>> i
4
Pemahaman dapat digunakan sebagai cara yang licik (atau mengerikan jika Anda mau) untuk membuat variabel yang dapat dimodifikasi dalam ekspresi lambda di Python 2 - ekspresi lambda memang menciptakan ruang lingkup variabel, seperti def
pernyataan itu, tetapi dalam lambda tidak ada pernyataan yang diizinkan. Penugasan sebagai pernyataan dalam Python berarti bahwa tidak ada penugasan variabel dalam lambda yang diizinkan, tetapi pemahaman daftar adalah ekspresi ...
Perilaku ini telah diperbaiki dalam Python 3 - tidak ada ekspresi pemahaman atau variabel generator bocor.
Global benar-benar berarti ruang lingkup modul; modul python utama adalah __main__
; semua modul yang diimpor dapat diakses melalui sys.modules
variabel; untuk mendapatkan akses ke __main__
satu dapat menggunakan sys.modules['__main__']
, atau import __main__
; sangat dapat diterima untuk mengakses dan menetapkan atribut di sana; mereka akan ditampilkan sebagai variabel dalam lingkup global modul utama.
Jika suatu nama pernah ditugaskan ke dalam lingkup saat ini (kecuali dalam lingkup kelas), itu akan dianggap milik lingkup itu, jika tidak maka akan dianggap milik setiap lingkup terlampir yang ditugaskan ke variabel (itu mungkin tidak ditugaskan belum, atau tidak sama sekali), atau akhirnya ruang lingkup global. Jika variabel dianggap lokal, tetapi belum disetel, atau telah dihapus, membaca nilai variabel akan menghasilkan UnboundLocalError
, yang merupakan subkelas dari NameError
.
x = 5
def foobar():
print(x) # causes UnboundLocalError!
x += 1 # because assignment here makes x a local variable within the function
# call the function
foobar()
Lingkup dapat menyatakan bahwa ia secara eksplisit ingin memodifikasi variabel global (cakupan modul), dengan kata kunci global:
x = 5
def foobar():
global x
print(x)
x += 1
foobar() # -> 5
print(x) # -> 6
Ini juga dimungkinkan bahkan jika dibayangi dalam cakupan terlampir:
x = 5
y = 13
def make_closure():
x = 42
y = 911
def func():
global x # sees the global value
print(x, y)
x += 1
return func
func = make_closure()
func() # -> 5 911
print(x, y) # -> 6 13
Dalam python 2 tidak ada cara mudah untuk mengubah nilai dalam lingkup terlampir; biasanya ini disimulasikan dengan memiliki nilai yang bisa berubah, seperti daftar dengan panjang 1:
def make_closure():
value = [0]
def get_next_value():
value[0] += 1
return value[0]
return get_next_value
get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2
Namun dalam python 3, nonlocal
datang untuk menyelamatkan:
def make_closure():
value = 0
def get_next_value():
nonlocal value
value += 1
return value
return get_next_value
get_next = make_closure() # identical behavior to the previous example.
The nonlocal
dokumentasi mengatakan bahwa
Nama-nama yang tercantum dalam pernyataan nonlokal, tidak seperti yang tercantum dalam pernyataan global, harus merujuk ke binding yang sudah ada sebelumnya dalam lingkup terlampir (lingkup di mana ikatan baru harus dibuat tidak dapat ditentukan secara jelas).
yaitu nonlocal
selalu mengacu pada ruang lingkup non-global terluar terdalam di mana nama telah diikat (yaitu ditugaskan untuk, termasuk digunakan sebagai for
variabel target, dalam with
klausa, atau sebagai parameter fungsi).
Setiap variabel yang tidak dianggap lokal ke lingkup saat ini, atau ruang lingkup apa pun, adalah variabel global. Nama global dilihat dalam kamus global modul; jika tidak ditemukan, global kemudian dilihat dari modul builtins; nama modul diubah dari python 2 menjadi python 3; di python 2 dulu __builtin__
dan di python 3 sekarang disebut builtins
. Jika Anda menetapkan atribut modul builtin, modul tersebut akan terlihat setelahnya ke modul apa pun sebagai variabel global yang dapat dibaca, kecuali modul itu membayangi mereka dengan variabel globalnya sendiri dengan nama yang sama.
Membaca modul builtin juga bisa bermanfaat; misalkan Anda menginginkan fungsi cetak gaya python 3 di beberapa bagian file, tetapi bagian lain dari file masih menggunakan print
pernyataan. Di Python 2.6-2.7 Anda bisa mendapatkan print
fungsi Python 3 dengan:
import __builtin__
print3 = __builtin__.__dict__['print']
The from __future__ import print_function
sebenarnya tidak mengimpor print
fungsi di mana saja di Python 2 - bukan hanya menonaktifkan aturan parsing untuk print
pernyataan dalam modul saat ini, penanganan print
seperti variabel pengenal lainnya, dan dengan demikian memungkinkan print
fungsi mendongak di builtin.