Jenis "seumur hidup variabel" ini dikenal sebagai pelingkupan. Setelah membaca artikel ini, Anda akan mengetahui aturan pelingkupan Python. Ayo mulai
3 Cakupan PythonPython memiliki 3 cakupan
- Global. Di bagian utama naskah. Secara default, ini sudah berisi built-in. Anda dapat mengakses semua variabel global dengan Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment7 - Diselubungi. Di fungsi luar, jika ini adalah fungsi bersarang
- Lokal. Dalam fungsi saat ini. Anda dapat mengakses semua variabel lokal dengan Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment8. Di dalam skrip utama, Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment9
Anda dapat melihat ketiganya beraksi di sini
Ada titik krusial di sini
Cakupan variabel didefinisikan pada waktu kompilasi
Untuk alasan ini, kode berikut melontarkan pengecualian
def foo():print(min([1, 2, 3]))
min = lambda n: "local"foo()
melempar pengecualian
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
Pernyataan “global”.
Anda dapat menetapkan nilai ke variabel global dalam suatu fungsi dengan pernyataan global
x = "global"def foo():global x
x = "local"foo()
print(x) # gives "local"
Saya sangat jarang membutuhkan ini. Untuk memastikan bahwa saya tidak membingungkan apa pun, saya suka menggunakan kamus Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment7. Dalam hal ini, saya lebih suka menggunakan
globals()["x"] = "local"foo()
print(x) # gives "local"
Pernyataan "nonlokal".
Anda dapat menetapkan nilai ke variabel terlampir dengan pernyataan nonlocal
x = "global"def foo():x = "enclosed" def bar():
nonlocal x
x = "local" bar()
print(x) # gives "local"foo()
print(x) # gives "local"_
Contoh yang Membingungkan
Gambar oleh wokandapix (sumber)
Tambahkan elemen vs '+= [elemen]'
xs = []def foo():xs.append(42) # OKfoo()_
vs
xs = []def foo():xs +=[42] # UnboundLocalError: local variable 'xs'
# referenced before assignmentfoo()
Alasan mengapa yang pertama berhasil tetapi tidak yang kedua adalah karena yang pertama memanggil fungsi xs. Itu tidak pernah memberikan nilai ke xs. Yang kedua sama dengan
xs = []def foo():xs = xs + [42]foo()
Ketika Python mem-parsing penugasan x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"_1 , x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"2 diberi lingkup lokal. Namun dalam lingkup lokal, x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"_2 tidak ada sebelum x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"4 dijalankan. Oleh karena itu kesalahan
Pada contoh pertama dengan x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"_5 , cakupan global x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"2 digunakan. Karenanya kami tidak menghadapi masalah apa pun, karena itu didefinisikan dalam lingkup global
Cakupan global TIDAK kembali ke built-in
# prints 1print(min([1, 2, 3]))
min = lambda n: "local"
tetapi hal yang sama tidak berfungsi dalam lingkup lokal
# UnboundLocalError: local variable 'min' referenced before assignmentdef foo():
print(min([1, 2, 3]))
min = lambda n: "local"foo()
Alasannya adalah Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_9 dalam lingkup global. Meskipun built-in agak istimewa, mereka hidup dalam lingkup global
Penugasan
Yang ini membingungkan bagi orang-orang dengan latar belakang Java, C, atau C++. Ini adalah kode Python yang valid
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment0
Tetapi di Java Anda harus mendeklarasikannya terlebih dahulu agar dapat menggunakan variabel setelah perulangan
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_1
mypy
mypy adalah pemeriksa tipe yang tersebar luas untuk Python
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_2
Jadi mypy tidak suka Anda menetapkan string "foo" ke x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"8 , karena pertama kali membaca mengambil jalur x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"9 dan berasumsi bahwa x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"8 akan menjadi bilangan bulat
Maka Anda mungkin ingin melakukan ini
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_3
Anda dapat melihat bahwa mypy menganggap x = "global"def foo():
global x
x = "local"foo()
print(x) # gives "local"8 harus tipe yang sama dalam kedua kasus. Ini masuk akal karena jika tidak, analisis berikut mungkin menjadi sangat rumit
Percobaan berikutnya mungkin
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_4
Itu seharusnya diharapkan. Menetapkan x = "global"def foo():
globals()["x"] = "local"foo()
print(x) # gives "local"2 tidak mungkin untuk jenis yang tidak termasuk x = "global"def foo():
globals()["x"] = "local"foo()
print(x) # gives "local"2 — dan menambahkan x = "global"def foo():
globals()["x"] = "local"foo()
print(x) # gives "local"2 ke jenis itu dapat menyebabkan lebih banyak masalah di kemudian hari
Kamu bisa melakukan ini
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment5
Tapi saya juga bisa melihat saat ini terasa aneh. Yang mungkin lebih bersih adalah ini
Traceback (most recent call last):File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment_6
Ringkasan
Kami telah melihat tiga jenis cakupan di Python. Lokal, Terlampir, dan global. Kami telah melihat bahwa Anda dapat mengakses global dengan kata kunci x = "global"def foo():
globals()["x"] = "local"foo()
print(x) # gives "local"5 atau melalui kamus Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment7. Lokal dapat diakses dengan kamus Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment8 dan variabel terlampir dengan kata kunci x = "global"def foo():
globals()["x"] = "local"foo()
print(x) # gives "local"8. Ingatlah itu dan pelingkupan Python harus masuk akal 🙂