Anotasi Fungsi: PEP-3107
Saya berlari melintasi potongan kode yang menunjukkan penjelasan fungsi Python3. Konsepnya sederhana tapi saya tidak bisa memikirkan mengapa ini diimplementasikan dalam Python3 atau ada gunanya bagi mereka. Mungkin SO dapat mencerahkan saya?
Bagaimana itu bekerja:
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
... function body ...
Segala sesuatu yang mengikuti titik dua setelah argumen adalah 'anotasi', dan informasi yang mengikuti ->
adalah anotasi untuk nilai pengembalian fungsi.
foo.func_annotations akan mengembalikan kamus:
{'a': 'x',
'b': 11,
'c': list,
'return': 9}
Apa pentingnya memiliki ini tersedia?
python
function
annotations
python-3.x
agscala
sumber
sumber
foo.func_annotations
harusfoo.__annotations__
di python3?def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
artinyaJawaban:
Saya pikir ini sebenarnya hebat.
Berasal dari latar belakang akademis, saya dapat memberi tahu Anda bahwa anotasi telah membuktikan diri mereka tak ternilai karena memungkinkan penganalisa statis cerdas untuk bahasa seperti Java. Misalnya, Anda bisa mendefinisikan semantik seperti batasan negara, utas yang diizinkan untuk mengakses, batasan arsitektur, dll., Dan ada beberapa alat yang kemudian dapat membaca ini dan memprosesnya untuk memberikan jaminan di luar apa yang Anda dapatkan dari kompiler. Anda bahkan dapat menulis hal-hal yang memeriksa prasyarat / postkondisi.
Saya merasa sesuatu seperti ini sangat diperlukan dalam Python karena pengetikannya yang lebih lemah, tetapi sebenarnya tidak ada konstruksi yang membuat ini mudah dan bagian dari sintaksis resmi.
Ada kegunaan lain untuk anotasi yang tidak dapat dijamin. Saya bisa melihat bagaimana saya bisa menerapkan alat berbasis Java ke Python. Sebagai contoh, saya memiliki alat yang memungkinkan Anda menetapkan peringatan khusus untuk metode, dan memberi Anda indikasi ketika Anda memanggil mereka bahwa Anda harus membaca dokumentasinya (Misalnya, bayangkan Anda memiliki metode yang tidak boleh dipanggil dengan nilai negatif, tapi itu tidak intuitif dari namanya). Dengan anotasi, saya bisa secara teknis menulis sesuatu seperti ini untuk Python. Demikian pula, alat yang mengatur metode dalam kelas besar berdasarkan tag dapat ditulis jika ada sintaksis resmi.
sumber
Anotasi fungsi adalah apa yang Anda buat darinya.
Mereka dapat digunakan untuk dokumentasi:
Mereka dapat digunakan untuk memeriksa pra-kondisi:
Juga lihat http://www.python.org/dev/peps/pep-0362/ untuk cara menerapkan pengecekan tipe.
sumber
Mass
danVelocity
sebagai gantinya.def kinetic_energy(mass: 'in kilograms', velocity: 'in meters per second') -> float:
menunjukkan tipe pengembalian. Ini jawaban favorit saya di sini.return
anotasi? Tampaknya tidak muncul dilocals
Ini adalah jawaban yang terlambat, tetapi AFAICT, penggunaan anotasi fungsi terbaik saat ini adalah PEP-0484 dan MyPy .
Digunakan seperti ini:
sumber
list(fib('a'))
dengan fungsi contoh Anda, Python 3.7 dengan senang hati menerima argumen dan mengeluh karena tidak ada cara untuk membandingkan string dan int.Hanya untuk menambahkan contoh spesifik dari penggunaan yang baik dari jawaban saya di sini , ditambah dengan dekorator mekanisme sederhana untuk metode multimetode dapat dilakukan.
dan contoh penggunaan:
Hal ini dapat dilakukan dengan menambahkan jenis ke dekorator seperti yang ditunjukkan oleh pos asli Guido , tetapi menganotasi parameter itu sendiri lebih baik karena menghindari kemungkinan kesalahan pencocokan parameter dan jenis.
Catatan : Dalam Python Anda dapat mengakses penjelasan sebagai
function.__annotations__
bukanfunction.func_annotations
sebagaifunc_*
gaya telah dihapus pada Python 3.sumber
function = self.typemap.get(types)
tidak akan berfungsi ketika subclass terlibat. Dalam hal ini Anda mungkin harus mengulangtypemap
menggunakanisinnstance
. Saya ingin tahu apakah@overload
menangani ini dengan benar__annotations__
adalahdict
yang tidak memastikan urutan argumen, sehingga cuplikan ini terkadang gagal. Saya akan merekomendasikan mengubahtypes = tuple(...)
kespec = inspect.getfullargspec(function)
kemudiantypes = tuple([spec.annotations[x] for x in spec.args])
.Uri telah memberikan jawaban yang tepat, jadi ini yang kurang serius: Jadi Anda bisa membuat dokumen Anda lebih singkat.
sumber
Pertama kali saya melihat anotasi, saya pikir "hebat! Akhirnya saya bisa ikut serta dalam pengecekan tipe!" Tentu saja, saya tidak memperhatikan bahwa anotasi sebenarnya tidak ditegakkan.
Jadi saya memutuskan untuk menulis dekorator fungsi sederhana untuk menegakkan mereka :
Saya menambahkannya ke perpustakaan Ensure .
sumber
Sudah lama sejak pertanyaan ini diajukan tetapi contoh cuplikan yang diberikan dalam pertanyaan adalah (sebagaimana dinyatakan di sana juga) dari PEP 3107 dan pada akhir contoh PEP contoh Penggunaan juga diberikan yang mungkin menjawab pertanyaan dari sudut pandang PEP dari lihat;)
Berikut ini dikutip dari PEP3107
Gunakan Kasing
Dalam perjalanan membahas anotasi, sejumlah use case telah dimunculkan. Beberapa di antaranya disajikan di sini, dikelompokkan berdasarkan jenis informasi apa yang mereka sampaikan. Juga termasuk contoh produk dan paket yang ada yang dapat menggunakan anotasi.
Lihat PEP untuk informasi lebih lanjut tentang poin-poin spesifik (dan juga referensi mereka)
sumber
Python 3.X (hanya) juga menggeneralisasikan definisi fungsi untuk memungkinkan argumen dan mengembalikan nilai yang akan dianotasi dengan nilai objek untuk digunakan dalam ekstensi .
Its META-data untuk menjelaskan, lebih eksplisit tentang nilai-nilai fungsi.
Anotasi dikodekan sebagai
:value
setelah nama argumen dan sebelum default, dan sebagai->value
setelah daftar argumen.Mereka dikumpulkan menjadi
__annotations__
atribut fungsi, tetapi tidak diperlakukan sebagai istimewa oleh Python itu sendiri:CONTOH:
The
typeannotations
modul menyediakan satu set alat untuk memeriksa jenis dan tipe inferensi kode Python. Ini juga menyediakan serangkaian jenis yang berguna untuk menjelaskan fungsi dan objek.Alat-alat ini terutama dirancang untuk digunakan oleh analis statis seperti linter, librari pelengkap kode dan IDE. Selain itu, dekorator untuk melakukan pemeriksaan run-time disediakan. Pemeriksaan jenis run-time tidak selalu merupakan ide yang baik dengan Python, tetapi dalam beberapa kasus ini bisa sangat berguna.
https://github.com/ceronman/typeannotations
Bagaimana Mengetik Membantu Menulis Kode Lebih Baik
PEP 526 - Sintaks untuk Anotasi Variabel
https://www.python.org/dev/peps/pep-0526/
https://www.attrs.org/en/stable/types.html
sumber
Terlepas dari semua penggunaan yang dijelaskan di sini, penggunaan anotasi yang diberlakukan dan, kemungkinan besar, akan diberlakukan untuk petunjuk jenis .
Ini saat ini tidak diberlakukan dengan cara apa pun tetapi, jika dilihat dari PEP 484, versi Python yang akan datang hanya akan memungkinkan jenis sebagai nilai untuk anotasi.
Mengutip Bagaimana dengan penggunaan anotasi yang ada? :
Meskipun saya belum melihat adanya penghinaan diam-diam di 3,6, ini bisa sangat baik dinaikkan menjadi 3,7, sebagai gantinya.
Jadi, meskipun mungkin ada beberapa kasus penggunaan yang baik, yang terbaik adalah menyimpannya hanya untuk mengetik petunjuk jika Anda tidak ingin mengubah segalanya di masa depan di mana pembatasan ini ada.
sumber
Sebagai sedikit jawaban yang tertunda, beberapa paket saya (marrow.script, WebCore, dll.) Menggunakan anotasi yang tersedia untuk menyatakan typecasting (yaitu mengubah nilai yang masuk dari web, mendeteksi argumen mana yang merupakan saklar boolean, dll.) untuk melakukan markup argumen tambahan.
Marrow Script membangun antarmuka baris perintah lengkap untuk fungsi dan kelas yang berubah-ubah dan memungkinkan untuk mendefinisikan dokumentasi, casting, dan nilai-nilai default yang diturunkan dari callback melalui anotasi, dengan dekorator untuk mendukung runtime yang lebih lama. Semua perpustakaan saya yang menggunakan anotasi mendukung formulir:
Dukungan "Bare" untuk fungsi docstring atau typecasting memungkinkan pencampuran yang lebih mudah dengan perpustakaan lain yang sadar akan anotasi. (Yaitu memiliki pengontrol web menggunakan typecasting yang juga akan diekspos sebagai skrip baris perintah.)
Diedit untuk menambahkan: Saya juga mulai menggunakan paket TypeGuard menggunakan pernyataan pengembangan untuk validasi. Manfaat: ketika dijalankan dengan "optimisasi" diaktifkan (
-O
/PYTHONOPTIMIZE
env var) cek, yang mungkin mahal (misalnya rekursif) dihilangkan, dengan gagasan bahwa Anda telah menguji aplikasi Anda dalam pengembangan dengan benar sehingga cek seharusnya tidak perlu dalam produksi.sumber
Anotasi dapat digunakan untuk mudah memodulasi kode. Misalnya modul untuk program yang saya pelihara hanya bisa mendefinisikan metode seperti:
dan kita bisa meminta pengguna untuk sesuatu bernama "param1" yang merupakan "Diperlukan untuk menghitung" dan harus menjadi "int". Pada akhirnya kita bahkan dapat mengubah string yang diberikan oleh pengguna ke tipe yang diinginkan untuk mendapatkan pengalaman bebas yang paling mudah.
Lihat kami fungsi objek metadata untuk kelas open source yang membantu dengan ini dan secara otomatis dapat mengambil nilai-nilai yang diperlukan dan mengkonversikannya ke setiap jenis yang diinginkan (karena anotasi adalah metode konversi). Bahkan IDE menunjukkan pelengkapan otomatis dengan benar dan menganggap bahwa tipe sesuai dengan anotasi - sangat cocok.
sumber
Jika Anda melihat daftar manfaat Cython, yang utama adalah kemampuan untuk memberi tahu kompiler jenis objek Python.
Saya bisa membayangkan masa depan di mana Cython (atau alat serupa yang mengkompilasi beberapa kode Python Anda) akan menggunakan sintaksis penjelasan untuk melakukan sihir mereka.
sumber
multiply
fungsi saya hanya bekerja melawan bilangan bulat, padahal'na' * 8 + ' batman!'
sepenuhnya valid? ;)