Python ialah bahasa yang mesra pemula. Walau bagaimanapun, ia juga mempunyai banyak ciri canggih yang sukar dikuasai, seperti penghias. Ramai pemula tidak pernah memahami penghias dan cara mereka bekerja Dalam artikel ini, kami akan memperkenalkan selok-belok penghias.
Dalam Python, fungsi ialah struktur yang sangat fleksibel Kita boleh menetapkannya kepada pembolehubah, menghantarnya sebagai parameter kepada fungsi lain atau menggunakannya sebagai output fungsi. Penghias pada asasnya ialah fungsi yang membenarkan fungsi lain menambah beberapa fungsi tanpa pengubahsuaian.
Ini ialah maksud "hiasan". "hiasan" ini sendiri mewakili fungsi Jika anda menggunakannya untuk mengubah suai fungsi yang berbeza, ia bermakna menambah fungsi ini.
Secara umumnya, kita boleh menggunakan gula @ sintaksis (Syntactic Sugar) yang disediakan oleh penghias untuk menghiasi fungsi atau objek lain. Seperti yang ditunjukkan di bawah, kami menggunakan penghias @dec untuk menghiasi fungsi fungsi ():
@dec def func(): pass
Cara terbaik untuk memahami penghias ialah memahami masalah yang diselesaikan oleh penghias dengan langkah bermula dari masalah khusus, dan tunjukkan keanggunan dan kuasanya.
Untuk memahami tujuan penghias, mari lihat contoh mudah. Katakan anda mempunyai fungsi penambahan ringkas dec.py Nilai lalai parameter kedua ialah 10:
# dec.py def add(x, y=10): return x + y
Mari kita lihat dengan lebih dekat fungsi penambahan ini:
>>> add(10, 20) 30 >>> add <function add at 0x7fce0da2fe18> >>> add.__name__ 'add' >>> add.__module__ '__main__' >>> add.__defaults__ # default value of the `add` function (10,) >>> add.__code__.co_varnames # the variable names of the `add` function ('x', 'y')
Kami tidak perlu memahami apa ini, cuma ingat bahawa setiap fungsi dalam Python adalah objek, dan mereka mempunyai pelbagai sifat dan kaedah. Anda juga boleh melihat kod sumber fungsi add() melalui modul inspect:
>>> from inspect import getsource >>> print(getsource(add)) def add(x, y=10): return x + y
Kini anda menggunakan fungsi penambahan dalam beberapa cara, contohnya anda menggunakan beberapa operasi untuk menguji fungsi:
# dec.py from time import time def add(x, y=10): return x + y print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b")) Output: i add(10) 20 add(20, 30) 50 add("a", "b") ab
Jika anda ingin tahu masa setiap operasi, anda boleh menghubungi modul masa:
# dec.py from time import time def add(x, y=10): return x + y before = time() print('add(10)', add(10)) after = time() print('time taken: ', after - before) before = time() print('add(20, 30)', add(20, 30)) after = time() print('time taken: ', after - before) before = time() print('add("a", "b")', add("a", "b")) after = time() print('time taken: ', after - before) Output: add(10) 20 time taken:6.699562072753906e-05 add(20, 30) 50 time taken:6.9141387939453125e-06 add("a", "b") ab time taken:6.9141387939453125e-06
Sekarang, sebagai pengaturcara, adakah anda sedikit gatal? tidak suka menyalin dan menampal kod yang sama sepanjang masa. Kod semasa tidak begitu mudah dibaca Jika anda ingin menukar sesuatu, anda perlu mengubah suai semua di mana ia muncul.
Kita boleh menangkap masa berjalan terus dalam fungsi tambah seperti berikut:
# dec.py from time import time def add(x, y=10): before = time() rv = x + y after = time() print('time taken: ', after - before) return rv print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b"))
Kaedah ini pastinya lebih baik daripada yang sebelumnya. Tetapi jika anda mempunyai fungsi lain, maka ini nampaknya menyusahkan. Apabila kita mempunyai berbilang fungsi:
# dec.py from time import time def add(x, y=10): before = time() rv = x + y after = time() print('time taken: ', after - before) return rv def sub(x, y=10): return x - y print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b")) print('sub(10)', sub(10)) print('sub(20, 30)', sub(20, 30))
Oleh kerana tambah dan sub ialah kedua-dua fungsi, kita boleh memanfaatkannya untuk menulis fungsi pemasa. Kami mahu pemasa mengira masa operasi fungsi:
def timer(func, x, y=10): before = time() rv = func(x, y) after = time() print('time taken: ', after - before) return rv
Ini bagus, tetapi kita mesti menggunakan fungsi pemasa untuk membalut fungsi yang berbeza, seperti berikut:
print('add(10)', timer(add,10)))
Adakah nilai lalai masih 10 sekarang? tidak semestinya. Jadi bagaimana untuk melakukannya dengan lebih baik?
Berikut ialah idea: buat fungsi pemasa baharu, balut dengan fungsi lain dan kembalikan fungsi yang dibalut:
def timer(func): def f(x, y=10): before = time() rv = func(x, y) after = time() print('time taken: ', after - before) return rv return f
Sekarang, anda hanya bungkusnya dengan pemasa Mari lihat pada fungsi tambah dan sub:
add = timer(add)
Itu sahaja! Berikut ialah kod lengkap:
# dec.py from time import time def timer(func): def f(x, y=10): before = time() rv = func(x, y) after = time() print('time taken: ', after - before) return rv return f def add(x, y=10): return x + y add = timer(add) def sub(x, y=10): return x - y sub = timer(sub) print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b")) print('sub(10)', sub(10)) print('sub(20, 30)', sub(20, 30)) Output: time taken:0.0 add(10) 20 time taken:9.5367431640625e-07 add(20, 30) 50 time taken:0.0 add("a", "b") ab time taken:9.5367431640625e-07 sub(10) 0 time taken:9.5367431640625e-07 sub(20, 30) -10
Mari kita ringkaskan proses: kita mempunyai fungsi (seperti fungsi tambah) dan kemudian membalut fungsi dengan tindakan (seperti pemasaan). Hasil pembungkusan adalah fungsi baru yang boleh melaksanakan fungsi baru tertentu.
Sudah tentu, terdapat masalah dengan nilai lalai, tetapi kami akan membetulkannya kemudian.
Kini, penyelesaian di atas sangat hampir dengan idea penghias, menggunakan tingkah laku biasa untuk membungkus fungsi tertentu Corak ini adalah hiasan peranti sedang melakukan. Kod selepas menggunakan penghias ialah:
def add(x, y=10): return x + y add = timer(add) You write: @timer def add(x, y=10): return x + y
Ia mempunyai kesan yang sama. Ini adalah peranan penghias Python. Fungsi yang dilaksanakannya adalah serupa dengan add = timer(add), kecuali penghias meletakkan sintaks di atas fungsi, dan sintaksnya lebih mudah: @timer.
# dec.py from time import time def timer(func): def f(x, y=10): before = time() rv = func(x, y) after = time() print('time taken: ', after - before) return rv return f @timer def add(x, y=10): return x + y @timer def sub(x, y=10): return x - y print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b")) print('sub(10)', sub(10)) print('sub(20, 30)', sub(20, 30))
Kini, masih ada masalah kecil yang belum selesai. Dalam fungsi pemasa, kami mengekod keras parameter x dan y, iaitu, menentukan nilai lalai y sebagai 10. Terdapat cara untuk menghantar argumen dan argumen kata kunci kepada fungsi, iaitu *args dan **kwargs. Parameter ialah parameter piawai bagi fungsi (dalam kes ini, x ialah parameter), dan parameter kata kunci ialah parameter yang sudah mempunyai nilai lalai (dalam kes ini, y=10). Kodnya adalah seperti berikut:
# dec.py from time import time def timer(func): def f(*args, **kwargs): before = time() rv = func(*args, **kwargs) after = time() print('time taken: ', after - before) return rv return f @timer def add(x, y=10): return x + y @timer def sub(x, y=10): return x - y print('add(10)', add(10)) print('add(20, 30)', add(20, 30)) print('add("a", "b")', add("a", "b")) print('sub(10)', sub(10)) print('sub(20, 30)', sub(20, 30))
Kini, fungsi pemasa boleh mengendalikan sebarang fungsi, sebarang parameter dan sebarang tetapan nilai lalai, kerana ia hanya menghantar parameter ini ke dalam fungsi.
Anda mungkin tertanya-tanya: jika kita boleh membungkus fungsi dengan fungsi lain untuk menambah gelagat berguna, bolehkah kita melangkah lebih jauh? Adakah kita membalut fungsi dengan fungsi lain dan dibalut oleh fungsi lain?
Ya! Malah, fungsinya boleh sedalam yang anda mahukan. Sebagai contoh, anda ingin menulis penghias yang melaksanakan fungsi n kali. Seperti yang ditunjukkan di bawah:
def ntimes(n): def inner(f): def wrapper(*args, **kwargs): for _ in range(n): rv = f(*args, **kwargs) return rv return wrapper return inner
Kemudian anda boleh menggunakan fungsi di atas untuk membungkus fungsi lain, seperti fungsi tambah dalam artikel sebelumnya:
@ntimes(3) def add(x, y): print(x + y) return x + y
Pernyataan output menunjukkan bahawa kod memang dilaksanakan 3 Second-rate.
Atas ialah kandungan terperinci Fahami penghias Python dalam satu artikel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!