penutupan

Terdapat banyak artikel yang memperkenalkan penutupan Python di Internet Artikel ini akan mempelajari tentang penutupan dengan menyelesaikan masalah keperluan.

Keperluan ini adalah seperti ini, kita perlu terus merekodkan masa belajar kita dalam beberapa minit. Macam kalau saya belajar 2 minit, saya balik 2. Kemudian lama-kelamaan, saya belajar 10 minit, dan kemudian saya kembali 12. Masa belajar terkumpul begini.

Menghadapi permintaan ini, kami biasanya mencipta pembolehubah global untuk merekodkan masa, dan kemudian menggunakan kaedah untuk menambah setiap masa pembelajaran, biasanya ditulis dalam bentuk berikut:

time = 0
def insert_time(min):
    time = time + min
    return  time
print(insert_time(2))
print(insert_time(10))

Fikirkan dengan teliti, adakah ada apa-apa yang berlaku? Apa masalahnya?

Sebenarnya, ini akan melaporkan ralat dalam Python. Ralat berikut akan dilaporkan:

UnboundLocalError: local variable 'time' referenced before assignment

Itu kerana, dalam Python, jika fungsi menggunakan nama yang sama dengan pembolehubah global dan menukar nilai pembolehubah, maka pembolehubah itu akan menjadi pembolehubah tempatan, yang akan menyebabkan Kami merujuk berfungsi tanpa mentakrifkannya, jadi ralat ini akan dilaporkan.

Jika anda benar-benar ingin merujuk pembolehubah global dan mengubah suainya dalam fungsi, apakah yang perlu anda lakukan?

Kita boleh menggunakan kata kunci global, dan pengubahsuaian khusus adalah seperti berikut:

time = 0
def insert_time(min):
    global  time
    time = time + min
    return  time
print(insert_time(2))
print(insert_time(10))

Hasil output adalah seperti berikut:

2
12

Tetapi, pembolehubah global digunakan di sini sebaik mungkin semasa pembangunan . Oleh kerana modul dan fungsi yang berbeza boleh mengakses pembolehubah global secara bebas, pembolehubah global mungkin tidak dapat diramalkan. Sebagai contoh, pengaturcara A mengubah suai nilai masa pembolehubah global, dan kemudian pengaturcara B juga mengubah suai masa Jika terdapat ralat, sukar untuk mencari dan membetulkannya.

Pembolehubah global mengurangkan kepelbagaian antara fungsi atau modul Fungsi atau modul yang berbeza bergantung pada pembolehubah global. Begitu juga, pembolehubah global mengurangkan kebolehbacaan kod, dan pembaca mungkin tidak tahu bahawa pembolehubah tertentu yang dipanggil ialah pembolehubah global.

Adakah cara yang lebih baik?

Pada masa ini, kami menggunakan penutupan untuk menyelesaikan masalah Pertama, lihat kod secara langsung:

time = 0
def study_time(time):
    def insert_time(min):
        nonlocal  time
        time = time + min
        return time
    return insert_time
f = study_time(time)
print(f(2))
print(time)
print(f(10))
print(time)

Hasil keluaran adalah seperti berikut:

2
0
12
0

Manifestasi paling langsung di sini ialah masa pembolehubah global tidak diubah suai. setakat ini, dan kunci bukan tempatan masih digunakan di sini, menunjukkan penggunaan pembolehubah luar (bukan global) dalam fungsi atau skop lain. Jadi apakah proses berjalan khusus kod di atas. Kita boleh lihat gambar di bawah:

a4e16c80e1df62cb932f66f1b8b91c9.png

Tingkah laku seperti ini di mana pembolehubah dalam skop tempatan fungsi luaran boleh diakses dalam skop tempatan fungsi dalaman dipanggil: penutupan. Cara yang lebih langsung untuk menyatakannya ialah apabila fungsi dikembalikan sebagai objek, pembolehubah luaran disertakan, membentuk penutupan. k

Penutupan mengelakkan penggunaan pembolehubah global Selain itu, penutupan membenarkan fungsi dikaitkan dengan beberapa data (persekitaran) yang ia beroperasi. Dan menggunakan penutupan boleh menjadikan kod lebih elegan. Dan penghias yang disebutkan dalam artikel seterusnya juga dilaksanakan berdasarkan penutupan.

Pada ketika ini, akan ada soalan Adakah anda fikir ia adalah penutupan atau penutupan? Adakah terdapat sebarang cara untuk mengesahkan bahawa fungsi ini adalah penutupan?

Ya, semua fungsi mempunyai atribut __closure__ Jika fungsi itu adalah penutup, maka ia mengembalikan objek tuple yang terdiri daripada sel. Sifat cell_contents objek sel ialah pembolehubah yang disimpan dalam penutupan.

Jom cetak dan rasainya:

time = 0
def study_time(time):
    def insert_time(min):
        nonlocal  time
        time = time + min
        return time
    return insert_time
f = study_time(time)
print(f.__closure__)
print(f(2))
print(time)
print(f.__closure__[0].cell_contents)
print(f(10))
print(time)
print(f.__closure__[0].cell_contents)

Hasil cetakan ialah:

(<cell at 0x0000000000410C48: int object at 0x000000001D6AB420>,)
2
0
2
12
0
12

Dapat dilihat daripada hasil cetakan bahawa nilai lulus sentiasa disimpan dalam sel_kandungan penutupan ciri penutupan Anda boleh Pembolehubah fungsi induk terikat kepada fungsi yang ditakrifkan di dalamnya. Walaupun fungsi induk yang menjana penutupan telah dikeluarkan, penutupan itu masih wujud.

Proses penutupan sebenarnya seperti kelas (fungsi induk) menjana contoh (penutupan) ialah fungsi induk hanya dilaksanakan apabila dipanggil, dan persekitarannya akan dikeluarkan selepas pelaksanaan, manakala kelas dicipta apabila). fail dilaksanakan Secara amnya Skop dikeluarkan selepas program dilaksanakan Oleh itu, untuk beberapa fungsi yang perlu digunakan semula dan tidak boleh ditakrifkan sebagai tingkah laku kelas, menggunakan penutupan akan menduduki lebih sedikit sumber daripada menggunakan kelas, dan lebih ringan. dan fleksibel.

Meneruskan pembelajaran
  • Cadangan kursus
  • Muat turun perisian kursus
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!