Salah satu fitur yang paling banyak dibicarakan di Python 3.5 adalah mengetikkan petunjuk .
Contoh petunjuk jenis disebutkan dalam artikel ini dan yang satu ini juga menyebutkan untuk menggunakan petunjuk jenis secara bertanggung jawab. Dapatkah seseorang menjelaskan lebih banyak tentang mereka dan kapan mereka harus digunakan dan kapan tidak?
python
python-3.x
python-3.5
type-hinting
Vaulstein
sumber
sumber
Jawaban:
Saya sarankan membaca PEP 483 dan PEP 484 dan menonton presentasi ini oleh Guido pada Type Hinting.
Singkatnya : Mengisyaratkan mengetik secara literal artinya, Anda mengisyaratkan jenis objek yang Anda gunakan .
Karena sifat dinamis Python, menyimpulkan atau memeriksa jenis objek yang digunakan sangat sulit. Fakta ini menyulitkan pengembang untuk memahami apa yang sebenarnya terjadi dalam kode yang belum mereka tulis dan, yang paling penting, untuk alat pengecekan tipe yang ditemukan di banyak IDE [PyCharm, PyDev datang ke pikiran] yang terbatas karena fakta bahwa mereka tidak memiliki indikator apa pun jenis objeknya. Akibatnya mereka resor untuk mencoba menyimpulkan tipe dengan (seperti yang disebutkan dalam presentasi) sekitar 50% tingkat keberhasilan.
Untuk mengambil dua slide penting dari presentasi Type Hinting:
Mengapa Mengetik Petunjuk?
TypeErrors
..
dan memiliki metode / atribut yang muncul yang tidak didefinisikan untuk objek.Mengapa menggunakan Pemeriksa Tipe Statis?
Sebagai catatan penutup untuk pengantar kecil ini : Ini adalah fitur opsional dan, dari apa yang saya mengerti, ini telah diperkenalkan untuk menuai beberapa manfaat dari pengetikan statis.
Anda umumnya tidak perlu khawatir tentang hal itu dan pasti tidak perlu menggunakannya (terutama dalam kasus di mana Anda menggunakan Python sebagai bahasa scripting tambahan). Seharusnya bermanfaat ketika mengembangkan proyek-proyek besar karena menawarkan ketahanan yang sangat dibutuhkan, kontrol dan kemampuan debugging tambahan .
Ketik Petunjuk dengan mypy :
Untuk membuat jawaban ini lebih lengkap, saya pikir sedikit demonstrasi akan cocok. Saya akan menggunakan
mypy
, perpustakaan yang menginspirasi Petunjuk Jenis saat mereka disajikan dalam PEP. Ini terutama ditulis untuk siapa saja yang menabrak pertanyaan ini dan bertanya-tanya harus mulai dari mana.Sebelum saya melakukannya, izinkan saya mengulangi yang berikut: PEP 484 tidak menegakkan apa pun; itu hanya menetapkan arah untuk penjelasan fungsi dan mengusulkan pedoman untuk bagaimana pemeriksaan tipe dapat / harus dilakukan. Anda dapat membuat anotasi fungsi Anda dan memberi petunjuk sebanyak mungkin hal yang Anda inginkan; skrip Anda akan tetap berjalan terlepas dari keberadaan anotasi karena Python sendiri tidak menggunakannya.
Bagaimanapun, sebagaimana dicatat dalam PEP, tipe-tipe yang mengisyaratkan umumnya harus mengambil tiga bentuk:
# type: type
Komentar khusus yang melengkapi dua bentuk pertama. (Lihat: Apa anotasi variabel dalam Python 3.6? Untuk pembaruan Python 3.6 untuk# type: type
komentar)Selain itu, Anda ingin menggunakan petunjuk jenis bersamaan dengan
typing
modul baru yang diperkenalkanPy3.5
. Di dalamnya, banyak (tambahan) ABC (Abstract Base Classes) didefinisikan bersama dengan fungsi pembantu dan dekorator untuk digunakan dalam pemeriksaan statis. KebanyakanABCs
dicollections.abc
dimasukkan tapi dalamGeneric
bentuk untuk memungkinkan berlangganan (dengan mendefinisikan__getitem__()
metode).Bagi siapa pun yang tertarik dengan penjelasan yang lebih mendalam tentang ini,
mypy documentation
ini ditulis dengan sangat baik dan memiliki banyak sampel kode yang menunjukkan / menggambarkan fungsi pemeriksa mereka; itu pasti layak dibaca.Anotasi fungsi dan komentar khusus:
Pertama, menarik untuk mengamati beberapa perilaku yang bisa kita dapatkan ketika menggunakan komentar khusus.
# type: type
Komentar khusus dapat ditambahkan selama penugasan variabel untuk menunjukkan jenis objek jika seseorang tidak dapat disimpulkan secara langsung. Penugasan sederhana umumnya mudah disimpulkan tetapi yang lain, seperti daftar (yang berkaitan dengan isinya), tidak bisa.Catatan: Jika kita ingin menggunakan turunan apa pun
Containers
dan perlu menentukan konten untuk wadah itu, kita harus menggunakan tipe generik darityping
modul. Ini mendukung pengindeksan.Jika kita menambahkan perintah ini ke file dan menjalankannya dengan juru bahasa kita, semuanya berfungsi dengan baik dan
print(a)
hanya mencetak isi daftara
. The# type
komentar telah dibuang, diperlakukan sebagai komentar polos yang tidak memiliki makna semantik tambahan .Dengan menjalankan ini dengan
mypy
, di sisi lain, kami mendapat respons berikut:Menunjukkan bahwa daftar
str
objek tidak dapat berisiint
, yang, secara statis, adalah suara. Ini dapat diperbaiki dengan mematuhi jenisa
dan hanya menambahkanstr
objek atau dengan mengubah jenis kontena
untuk menunjukkan bahwa nilai apa pun dapat diterima (Dilakukan secara intuitif denganList[Any]
setelahAny
diimpor darityping
).Anotasi fungsi ditambahkan dalam formulir
param_name : type
setelah setiap parameter dalam tanda tangan fungsi Anda dan tipe pengembalian ditentukan menggunakan-> type
notasi sebelum tanda titik dua fungsi; semua anotasi disimpan dalam__annotations__
atribut untuk fungsi itu dalam bentuk kamus yang praktis. Menggunakan contoh sepele (yang tidak memerlukan jenis tambahan darityping
modul):The
annotated.__annotations__
atribut sekarang memiliki nilai-nilai berikut:Jika kita benar-benar noobie, atau kita terbiasa dengan
Py2.7
konsep dan akibatnya tidak mengetahuiTypeError
mengintai dalam perbandinganannotated
, kita dapat melakukan pemeriksaan statis lain, menangkap kesalahan dan menyelamatkan kita dari beberapa masalah:Antara lain, memanggil fungsi dengan argumen yang tidak valid juga akan ketahuan:
Ini pada dasarnya dapat diperluas ke kasus penggunaan apa saja dan kesalahan yang ditangkap meluas lebih jauh dari panggilan dasar dan operasi. Jenis-jenis yang dapat Anda periksa benar-benar fleksibel dan saya hanya memberi sedikit kemungkinan. Melihat
typing
modul, PEPs ataumypy
dokumen akan memberi Anda ide yang lebih komprehensif dari kemampuan yang ditawarkan.File rintisan:
File rintisan dapat digunakan dalam dua kasus berbeda yang tidak saling eksklusif:
File rintisan apa (dengan ekstensi
.pyi
) adalah antarmuka beranotasi dari modul yang Anda buat / ingin gunakan. Mereka berisi tanda tangan dari fungsi yang ingin Anda ketik-periksa dengan tubuh fungsi dibuang. Untuk merasakan hal ini, diberikan satu set tiga fungsi acak dalam sebuah modul bernamarandfunc.py
:Kita dapat membuat file rintisan
randfunc.pyi
, di mana kita dapat menempatkan beberapa batasan jika kita ingin melakukannya. Kelemahannya adalah seseorang yang melihat sumber tanpa rintisan tidak akan benar-benar mendapatkan bantuan anotasi ketika mencoba memahami apa yang seharusnya diteruskan ke mana.Bagaimanapun, struktur file rintisan cukup sederhana: Tambahkan semua definisi fungsi dengan badan kosong (
pass
diisi) dan berikan penjelasan berdasarkan kebutuhan Anda. Di sini, mari kita asumsikan kita hanya ingin bekerja denganint
tipe untuk Kontainer kita.The
combine
Fungsi memberikan indikasi mengapa Anda mungkin ingin menggunakan anotasi dalam file yang berbeda, mereka beberapa kali mengacaukan kode dan mengurangi keterbacaan (besar tidak-tidak untuk Python). Anda tentu saja bisa menggunakan alias ketik tetapi kadang-kadang membingungkan lebih dari itu membantu (jadi gunakan dengan bijak).Ini akan membuat Anda terbiasa dengan konsep dasar Tip Petunjuk dalam Python. Meskipun pemeriksa tipe yang digunakan adalah
mypy
Anda harus secara bertahap mulai melihat lebih banyak dari mereka yang muncul, beberapa secara internal di IDE ( PyCharm ,) dan lainnya sebagai modul python standar. Saya akan mencoba dan menambahkan checker tambahan / paket terkait dalam daftar berikut kapan dan jika saya menemukannya (atau jika disarankan).Dam yang saya tahu :
Paket / Proyek Terkait :
The
typeshed
proyek sebenarnya adalah salah satu tempat terbaik yang Anda dapat melihat untuk melihat bagaimana jenis mengisyaratkan mungkin digunakan dalam proyek Anda sendiri. Mari kita mengambil sebagai contoh yang__init__
Dunders dariCounter
kelas di yang sesuai.pyi
berkas:Di mana
_T = TypeVar('_T')
digunakan untuk mendefinisikan kelas generik . UntukCounter
kelas kita dapat melihat bahwa ia tidak dapat mengambil argumen di penginisialisasi, mendapatkan satuMapping
dari jenis apa pun keint
atau mengambilIterable
jenis apa pun.Perhatikan : Satu hal yang saya lupa sebutkan adalah bahwa
typing
modul telah diperkenalkan secara sementara . Dari PEP 411 :Jadi bawalah semuanya ke sini dengan sejumput garam; Saya ragu apakah itu akan dihapus atau diubah secara signifikan tetapi orang tidak akan pernah tahu.
** Topik lain sama sekali tetapi valid dalam lingkup type-hints::
PEP 526
Sintaks untuk Anotasi Variabel adalah upaya untuk mengganti# type
komentar dengan memperkenalkan sintaks baru yang memungkinkan pengguna untuk membubuhi keterangan jenis variabel dalamvarname: type
pernyataan sederhana .Lihat Apa anotasi variabel dalam Python 3.6? , seperti yang disebutkan sebelumnya, untuk intro kecil tentang ini.
sumber
Menambahkan ke jawaban rumit Jim:
Periksa
typing
modul - modul ini mendukung petunjuk jenis seperti yang ditentukan oleh PEP 484 .Misalnya, fungsi di bawah ini mengambil dan mengembalikan nilai tipe
str
dan dijelaskan sebagai berikut:The
typing
Modul juga mendukung:sumber
PyCharm 5 yang baru dirilis mendukung isyarat tipe. Dalam posting blog mereka tentang hal itu (lihat petunjuk jenis Python 3.5 di PyCharm 5 ) mereka menawarkan penjelasan yang bagus tentang jenis petunjuk apa dan tidak disertai dengan beberapa contoh dan ilustrasi tentang cara menggunakannya dalam kode Anda.
Selain itu, didukung dalam Python 2.7, seperti yang dijelaskan dalam komentar ini :
sumber
Petunjuk jenis adalah tambahan baru untuk bahasa dinamis di mana selama beberapa dekade orang bersumpah konvensi penamaan semudah bahasa Hongaria (label objek dengan huruf pertama b = boolian, c = karakter, d = kamus, i = integer, l = daftar, n = numerik , s = string, t = tuple) tidak diperlukan, terlalu rumit, tetapi sekarang telah memutuskan bahwa, oh tunggu ... terlalu banyak kesulitan untuk menggunakan bahasa (tipe ()) untuk mengenali objek, dan IDE mewah kami butuh bantuan melakukan apa pun yang rumit, dan nilai-nilai objek yang ditetapkan secara dinamis membuat mereka benar-benar tidak berguna bagaimanapun, sedangkan konvensi penamaan sederhana bisa menyelesaikan semua itu, untuk setiap pengembang, hanya dengan pandangan sekilas.
sumber
Tipe-petunjuk adalah untuk pemeliharaan dan jangan ditafsirkan oleh Python. Dalam kode di bawah ini, baris
def add(self, ic:int)
tersebut tidak menghasilkan kesalahan sampaireturn...
baris berikutnya :sumber