Pada Python versi 3. 7, kamus dipesan. Dalam Python 3. 6 dan sebelumnya, kamus tidak diurutkan
Kamus ditulis dengan tanda kurung kurawal, dan memiliki kunci dan nilai
Contoh
Membuat dan mencetak kamus
inidikt = {
"merek". "Mengarungi",
"model". "Mustang",
"tahun". 1964
}
cetak [inidikt]
Item Kamus
Item kamus dipesan, diubah, dan tidak memungkinkan duplikat
Item kamus disajikan dalam kunci. pasangan nilai, dan dapat dirujuk dengan menggunakan nama kunci
Contoh
Cetak nilai "merek" kamus
inidikt = {
"merek". "Mengarungi",
"model". "Mustang",
"tahun". 1964
}
cetak[inidict["merek"]]
Diurutkan atau Tidak Diurutkan?
Pada Python versi 3. 7, kamus dipesan. Dalam Python 3. 6 dan sebelumnya, kamus tidak diurutkan
Ketika kami mengatakan bahwa kamus diurutkan, itu berarti item memiliki urutan yang ditentukan, dan urutan itu tidak akan berubah
Unordered berarti item tidak memiliki urutan yang ditentukan, Anda tidak dapat merujuk ke item dengan menggunakan indeks
Dapat diubah
Kamus dapat diubah, artinya kita dapat mengubah, menambah atau menghapus item setelah kamus dibuat
Duplikat Tidak Diizinkan
Kamus tidak boleh memiliki dua item dengan kunci yang sama
Contoh
Nilai duplikat akan menimpa nilai yang ada
inidikt = {
"merek". "Mengarungi",
"model". "Mustang",
"tahun". 1964,
"tahun". 2020
}
cetak [inidikt]
Belajar Memfilter Data dengan Python Seperti Analis Data
Cobalah sesi pelatihan langsung dengan panduan langkah demi langkah dari seorang ahli. Coba proyek terpandu yang dibuat bekerja sama dengan Coursera sekarang
Get startedPanjang Kamus
Untuk menentukan berapa banyak item yang dimiliki kamus, gunakan fungsi len[]
Item Kamus - Tipe Data
Nilai dalam item kamus dapat berupa tipe data apa pun
Contoh
Tipe data string, int, boolean, dan daftar
inidikt = {
"merek". "Mengarungi",
"listrik". PALSU,
"tahun". 1964,
"warna". ["merah", "putih", "biru"]
}
jenis[]
Dari perspektif Python, kamus didefinisikan sebagai objek dengan tipe data 'dict'
Contoh
Cetak tipe data kamus
inidikt = {
"merek". "Mengarungi",
"model". "Mustang",
"tahun". 1964
}
cetak[ketik[inidict]]
Konstruktor dict[]
Dimungkinkan juga untuk menggunakan konstruktor dict[] untuk membuat kamus
Contoh
Menggunakan metode dict[] untuk membuat kamus
thisdict = dict[nama = "John", umur = 36, negara = "Norwegia"]
cetak [inidikt]
Koleksi Python [Array]
Ada empat tipe data koleksi dalam bahasa pemrograman Python
- Daftar adalah koleksi yang dipesan dan diubah. Memungkinkan duplikat anggota
- Tuple adalah koleksi yang dipesan dan tidak dapat diubah. Memungkinkan duplikat anggota
- Set adalah koleksi yang tidak diurutkan, tidak dapat diubah*, dan tidak diindeks. Tidak ada anggota rangkap
- Kamus adalah kumpulan yang dipesan** dan dapat diubah. Tidak ada anggota rangkap
*Set item tidak dapat diubah, tetapi Anda dapat menghapus dan/atau menambahkan item kapan pun Anda mau
**Pada Python versi 3. 7, kamus dipesan. Dalam Python 3. 6 dan sebelumnya, kamus tidak diurutkan
Saat memilih tipe koleksi, akan sangat berguna untuk memahami properti dari tipe tersebut. Memilih jenis yang tepat untuk kumpulan data tertentu dapat berarti retensi makna, dan dapat berarti peningkatan efisiensi atau keamanan
PEP 484 mendefinisikan tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int1 untuk kamus seragam, di mana setiap nilai memiliki tipe yang sama, dan nilai kunci arbitrer didukung. Itu tidak mendukung pola umum dengan benar di mana jenis nilai kamus bergantung pada nilai string kunci. PEP ini mengusulkan konstruktor tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int2 untuk mendukung kasus penggunaan di mana objek kamus memiliki kumpulan kunci string tertentu, masing-masing dengan nilai tipe tertentu
Berikut adalah contoh di mana PEP 484 tidak memungkinkan kami membuat anotasi dengan memuaskan
movie = {'name': 'Blade Runner', 'year': 1982}
PEP ini mengusulkan penambahan konstruktor tipe baru, yang disebut
from typing import TypedDict class Movie[TypedDict]: name: str year: int3, agar tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int4 dapat direpresentasikan dengan tepat
from typing import TypedDict class Movie[TypedDict]: name: str year: int
Sekarang pemeriksa tipe harus menerima kode ini
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_
Mewakili objek atau data terstruktur menggunakan kamus [berpotensi bersarang] dengan kunci string [bukan kelas yang ditentukan pengguna] adalah pola umum dalam program Python. Mewakili objek JSON mungkin merupakan kasus penggunaan kanonis, dan ini cukup populer sehingga Python dikirimkan dengan pustaka JSON. PEP ini mengusulkan cara agar kode semacam itu dapat diperiksa jenisnya dengan lebih efektif
Secara lebih umum, merepresentasikan objek data murni hanya menggunakan tipe primitif Python seperti kamus, string, dan daftar memiliki daya tarik tertentu. Mereka mudah untuk membuat serial dan deserialisasi bahkan saat tidak menggunakan JSON. Mereka dengan mudah mendukung berbagai operasi yang berguna tanpa usaha ekstra, termasuk pencetakan cantik [melalui
from typing import TypedDict class Movie[TypedDict]: name: str year: int5 dan modul
from typing import TypedDict class Movie[TypedDict]: name: str year: int6], iterasi, dan perbandingan kesetaraan
PEP 484 tidak mendukung kasus penggunaan yang disebutkan di atas dengan benar. Mari pertimbangkan objek kamus yang memiliki tepat dua kunci string yang valid,
from typing import TypedDict class Movie[TypedDict]: name: str year: int7 dengan tipe nilai
from typing import TypedDict class Movie[TypedDict]: name: str year: int8, dan
from typing import TypedDict class Movie[TypedDict]: name: str year: int9 dengan tipe nilai
class EmptyDict[TypedDict]: pass0. Tipe PEP 484
class EmptyDict[TypedDict]: pass1 akan cocok, tetapi terlalu lunak, karena kunci string arbitrer dapat digunakan, dan nilai arbitrer valid. Demikian pula,
class EmptyDict[TypedDict]: pass_2 terlalu umum, karena nilai untuk kunci
from typing import TypedDict class Movie[TypedDict]: name: str year: int7 bisa menjadi
class EmptyDict[TypedDict]: pass0, dan kunci string arbitrer diperbolehkan. Selain itu, jenis ekspresi berlangganan seperti
class EmptyDict[TypedDict]: pass5 [dengan asumsi
class EmptyDict[TypedDict]: pass6 menjadi kamus jenis ini] akan menjadi
class EmptyDict[TypedDict]: pass7, yang terlalu lebar
Kelas data adalah alternatif yang lebih baru untuk menyelesaikan kasus penggunaan ini, tetapi masih ada banyak kode yang ditulis sebelum kelas data tersedia, terutama di basis kode besar yang sudah ada di mana petunjuk dan pemeriksaan tipe terbukti membantu. Tidak seperti objek kamus, kelas data tidak secara langsung mendukung serialisasi JSON, meskipun ada paket pihak ketiga yang mengimplementasikannya
Tipe TypedDict mewakili objek kamus dengan serangkaian kunci string tertentu, dan dengan tipe nilai tertentu untuk setiap kunci yang valid. Setiap kunci string dapat berupa wajib [harus ada] atau tidak wajib [tidak perlu ada]
PEP ini mengusulkan dua cara untuk mendefinisikan tipe TypedDict. Yang pertama menggunakan sintaks berbasis kelas. Yang kedua adalah sintaks berbasis penugasan alternatif yang disediakan untuk kompatibilitas mundur, untuk memungkinkan fitur di-backport ke versi Python yang lebih lama. Alasannya mirip dengan mengapa PEP 484 mendukung sintaks anotasi berbasis komentar untuk Python 2. 7. petunjuk tipe sangat berguna untuk basis kode besar yang sudah ada, dan ini sering kali perlu dijalankan pada versi Python yang lebih lama. Kedua opsi sintaks sejajar dengan varian sintaks yang didukung oleh
class EmptyDict[TypedDict]: pass8. Fitur lain yang diusulkan termasuk pewarisan dan totalitas TypedDict [menentukan apakah kunci diperlukan atau tidak]
PEP ini juga menyediakan sketsa tentang bagaimana pemeriksa tipe diharapkan mendukung operasi pemeriksaan tipe yang melibatkan objek TypedDict. Mirip dengan PEP 484, diskusi ini sengaja dibuat agak kabur, untuk memungkinkan eksperimen dengan berbagai jenis pendekatan pemeriksaan yang berbeda. Secara khusus, kompatibilitas tipe harus didasarkan pada kompatibilitas struktural. tipe TypedDict yang lebih spesifik dapat kompatibel dengan tipe TypedDict yang lebih kecil [lebih umum].
Tipe TypedDict dapat didefinisikan menggunakan sintaks definisi kelas dengan
from typing import TypedDict class Movie[TypedDict]: name: str year: int2 sebagai satu-satunya kelas dasar
from typing import TypedDict class Movie[TypedDict]: name: str year: int
movie: Movie = {'name': 'Blade Runner', 'year': 1982}0 adalah tipe TypedDict dengan dua item.
from typing import TypedDict class Movie[TypedDict]: name: str year: int7 [dengan tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int8] dan
from typing import TypedDict class Movie[TypedDict]: name: str year: int9 [dengan tipe
class EmptyDict[TypedDict]: pass0]
Pemeriksa tipe harus memvalidasi bahwa badan definisi TypedDict berbasis kelas sesuai dengan aturan berikut
- Badan kelas hanya boleh berisi baris dengan definisi item dalam bentuk
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
5, secara opsional diawali dengan docstring. Sintaks untuk definisi item identik dengan anotasi atribut, tetapi tidak boleh ada penginisialisasi, dan nama kunci sebenarnya mengacu pada nilai string kunci, bukan nama atribut - Ketik komentar tidak dapat digunakan dengan sintaks berbasis kelas, untuk konsistensi dengan sintaks
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
6 berbasis kelas. [Perhatikan bahwa itu tidak akan cukup untuk mendukung komentar tipe untuk kompatibilitas mundur dengan Python 2. 7, karena definisi kelas mungkin memiliki argumen kata kuncimovie: Movie = {'name': 'Blade Runner', 'year': 1982}
7, seperti yang dibahas di bawah, dan ini bukan sintaks yang valid di Python 2. 7. ] Sebagai gantinya, PEP ini menyediakan alternatif, sintaksis berbasis penugasan untuk kompatibilitas mundur, yang dibahas di - Referensi penerusan literal string valid dalam tipe nilai
- Metode tidak diperbolehkan, karena tipe runtime dari objek TypedDict akan selalu hanya
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
8 [tidak pernah merupakan subkelas darimovie: Movie = {'name': 'Blade Runner', 'year': 1982}
8] - Menentukan metaclass tidak diperbolehkan
TypedDict kosong dapat dibuat hanya dengan memasukkan
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]0 di badan [jika ada docstring,
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]0 dapat dihilangkan]
class EmptyDict[TypedDict]: pass
Berikut adalah contoh bagaimana tipe
movie: Movie = {'name': 'Blade Runner', 'year': 1982}0 dapat digunakan
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_
Anotasi tipe
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_0 eksplisit umumnya diperlukan, karena jika tidak, tipe kamus biasa dapat diasumsikan oleh pemeriksa tipe, untuk kompatibilitas mundur. Ketika pemeriksa tipe dapat menyimpulkan bahwa objek kamus yang dibangun harus berupa TypedDict, anotasi eksplisit dapat dihilangkan. Contoh tipikal adalah objek kamus sebagai argumen fungsi. Dalam contoh ini, pemeriksa tipe diharapkan menyimpulkan bahwa argumen kamus harus dipahami sebagai TypedDict
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]
Contoh lain di mana pemeriksa tipe harus memperlakukan tampilan kamus sebagai TypedDict adalah penugasan ke variabel dengan tipe TypedDict yang dideklarasikan sebelumnya
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}
Operasi pada
from typing import TypedDict class Movie[TypedDict]: name: str year: int_4 dapat diperiksa dengan pemeriksa tipe statis
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]
Kode di bawah ini harus ditolak, karena
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]5 bukan kunci yang valid, dan kunci
from typing import TypedDict class Movie[TypedDict]: name: str year: int7 tidak ada
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}
Objek tipe TypedDict yang dibuat bukanlah objek kelas nyata. Berikut adalah satu-satunya penggunaan tipe yang diharapkan diizinkan oleh pemeriksa tipe
- Ini dapat digunakan dalam anotasi tipe dan dalam konteks apa pun di mana petunjuk tipe arbitrer valid, seperti dalam alias tipe dan sebagai tipe target pemeran
- Itu dapat digunakan sebagai objek yang dapat dipanggil dengan argumen kata kunci yang sesuai dengan item TypedDict. Argumen non-kata kunci tidak diperbolehkan. Contoh
from typing import TypedDict class Movie[TypedDict]: name: str year: int
0Saat dipanggil, objek tipe TypedDict mengembalikan objek kamus biasa saat runtime
from typing import TypedDict class Movie[TypedDict]: name: str year: int
_1 - Itu dapat digunakan sebagai kelas dasar, tetapi hanya ketika mendefinisikan turunan TypedDict. Ini dibahas secara lebih rinci di bawah ini
Secara khusus, objek tipe TypedDict tidak dapat digunakan dalam pengujian
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]7 seperti
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]8. Alasannya adalah tidak ada dukungan untuk memeriksa jenis nilai item kamus, karena
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]7 tidak berfungsi dengan banyak jenis PEP 484, termasuk yang umum seperti
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}0. Ini akan diperlukan untuk kasus-kasus seperti ini
from typing import TypedDict class Movie[TypedDict]: name: str year: int_2
Kasus penggunaan di atas tidak didukung. Ini konsisten dengan bagaimana
def record_movie[movie: Movie] -> None: ... record_movie[{'name': 'Blade Runner', 'year': 1982}]_7 tidak didukung untuk
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}0
Dimungkinkan untuk tipe TypedDict untuk mewarisi dari satu atau lebih tipe TypedDict menggunakan sintaks berbasis kelas. Dalam hal ini kelas dasar
from typing import TypedDict class Movie[TypedDict]: name: str year: int3 tidak boleh disertakan. Contoh
from typing import TypedDict class Movie[TypedDict]: name: str year: int_3
Sekarang
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}_4 memiliki kunci
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}5,
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}6, dan
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}7. Ini setara dengan definisi ini, karena tipe TypedDict menggunakan kompatibilitas struktural
from typing import TypedDict class Movie[TypedDict]: name: str year: int_4
Berikut adalah contoh pewarisan berganda
from typing import TypedDict class Movie[TypedDict]: name: str year: int5
TypedDict
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}8 memiliki tiga item.
movie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}_9 [tipe
class EmptyDict[TypedDict]: pass0],
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]1 [tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int8], dan
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]3 [tipe
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]4]
TypedDict tidak dapat mewarisi dari tipe TypedDict dan kelas dasar non-TypedDict
Catatan tambahan tentang pewarisan kelas TypedDict
- Mengubah jenis bidang induk kelas TypedDict dalam subkelas tidak diperbolehkan. Contoh
from typing import TypedDict class Movie[TypedDict]: name: str year: int
_6Dalam contoh yang diuraikan di atas, anotasi kelas TypedDict mengembalikan tipe
from typing import TypedDict class Movie[TypedDict]: name: str year: int
8 untuk kuncimovie: Movie ... movie = {'name': 'Blade Runner', 'year': 1982}
9from typing import TypedDict class Movie[TypedDict]: name: str year: int
_7 - Warisan berganda tidak mengizinkan jenis konflik untuk bidang nama yang sama
from typing import TypedDict class Movie[TypedDict]: name: str year: int
_8
Secara default, semua kunci harus ada di TypedDict. Dimungkinkan untuk mengesampingkan ini dengan menentukan totalitas. Berikut ini cara melakukannya menggunakan sintaks berbasis kelas
from typing import TypedDict class Movie[TypedDict]: name: str year: int_9
Ini berarti bahwa
movie: Movie = {'name': 'Blade Runner', 'year': 1982}0 TypedDict dapat memiliki salah satu kunci yang dihilangkan. Jadi ini valid
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_0
Pemeriksa tipe hanya diharapkan mendukung literal
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]8 atau
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]9 sebagai nilai dari argumen
movie: Movie = {'name': 'Blade Runner', 'year': 1982}7.
movie['director'] = 'Ridley Scott' # Error: invalid key 'director' movie['year'] = '1982' # Error: invalid value type ["int" expected]9 adalah default, dan membuat semua item yang ditentukan dalam badan kelas wajib diisi
Bendera totalitas hanya berlaku untuk item yang ditentukan dalam badan definisi TypedDict. Item yang diwariskan tidak akan terpengaruh, dan sebagai gantinya gunakan totalitas tipe TypedDict tempat item tersebut ditentukan. Ini memungkinkan untuk memiliki kombinasi kunci yang diperlukan dan tidak diperlukan dalam satu tipe TypedDict
PEP ini juga mengusulkan sintaks alternatif yang dapat di-backport ke versi Python lama seperti 3. 5 dan 2. 7 yang tidak mendukung sintaks definisi variabel yang diperkenalkan di PEP 526. Itu menyerupai sintaks tradisional untuk mendefinisikan tupel bernama
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_1
Dimungkinkan juga untuk menentukan totalitas menggunakan sintaks alternatif
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_2
Semantik setara dengan sintaks berbasis kelas. Sintaks ini tidak mendukung pewarisan, dan tidak ada cara untuk memiliki bidang wajib dan tidak wajib dalam satu jenis. Motivasi untuk ini adalah menjaga sintaks yang kompatibel ke belakang sesederhana mungkin sambil mencakup kasus penggunaan yang paling umum
Pemeriksa tipe hanya diharapkan menerima ekspresi tampilan kamus sebagai argumen kedua untuk
from typing import TypedDict class Movie[TypedDict]: name: str year: int3. Secara khusus, variabel yang merujuk ke objek kamus tidak perlu didukung, untuk menyederhanakan implementasi
Berbicara secara informal, konsistensi tipe adalah generalisasi dari relasi is-subtype-of untuk mendukung tipe
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}3. Ini didefinisikan lebih formal dalam PEP 483. Bagian ini memperkenalkan aturan nontrivial baru yang diperlukan untuk mendukung konsistensi tipe untuk tipe TypedDict
Pertama, tipe TypedDict apa pun konsisten dengan
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}4. Kedua, tipe TypedDict
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}5 konsisten dengan TypedDict
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}6 jika
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}5 secara struktural kompatibel dengan
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}6. Ini benar jika dan hanya jika kedua kondisi ini terpenuhi
- Untuk setiap kunci di
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}
_6,movie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5 memiliki kunci yang sesuai dan jenis nilai yang sesuai dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5 konsisten dengan jenis nilai dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
6. Untuk setiap kunci dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
6, tipe nilai dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
6 juga konsisten dengan tipe nilai yang sesuai dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5 - Untuk setiap kunci yang diperlukan di
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}
_6, kunci yang sesuai diperlukan dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5. Untuk setiap kunci yang tidak diperlukan dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
6, kunci yang sesuai tidak diperlukan dimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5
Diskusi
- Tipe nilai berperilaku invarian, karena objek TypedDict bisa berubah. Ini mirip dengan jenis wadah yang dapat berubah seperti
from typing import TypedDict class Movie[TypedDict]: name: str year: int
10 danfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
11. Contoh di mana ini relevanmovie: Movie = {'name': 'Blade Runner', 'year': 1982}
_3 - Tipe TypedDict dengan kunci yang diperlukan tidak konsisten dengan tipe TypedDict di mana kunci yang sama adalah kunci yang tidak diperlukan, karena yang terakhir memungkinkan kunci dihapus. Contoh di mana ini relevan
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
_4 - Tipe TypedDict
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5 tanpa kuncifrom typing import TypedDict class Movie[TypedDict]: name: str year: int
13 tidak konsisten dengan tipe TypedDict dengan kunci yang tidak diperlukanfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
13, karena saat runtime kuncifrom typing import TypedDict class Movie[TypedDict]: name: str year: int
13 dapat hadir dan memiliki tipe yang tidak kompatibel [yang mungkin tidak terlihat melaluimovie2: Movie = {'title': 'Blade Runner', 'year': 1982}
5 karena subtipe struktural]. Contohmovie: Movie = {'name': 'Blade Runner', 'year': 1982}
_5 - TypedDict tidak konsisten dengan jenis
from typing import TypedDict class Movie[TypedDict]: name: str year: int
17 apa pun, karena jenis kamus memungkinkan operasi destruktif, termasukfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
18. Mereka juga mengizinkan kunci sewenang-wenang untuk disetel, yang akan membahayakan keamanan jenis. Contohmovie: Movie = {'name': 'Blade Runner', 'year': 1982}
_6 - TypedDict dengan semua nilai
class EmptyDict[TypedDict]: pass
_0 tidak konsisten denganfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
20, karena mungkin ada nilai non-class EmptyDict[TypedDict]: pass
0 tambahan yang tidak terlihat melalui tipe, karena subtipe struktural. Ini dapat diakses menggunakan metodefrom typing import TypedDict class Movie[TypedDict]: name: str year: int
_22 danfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
23 difrom typing import TypedDict class Movie[TypedDict]: name: str year: int
24, misalnya. Contohmovie: Movie = {'name': 'Blade Runner', 'year': 1982}
_7
Pemeriksa tipe harus mendukung bentuk terbatas dari sebagian besar operasi
movie: Movie = {'name': 'Blade Runner', 'year': 1982}8 pada objek TypedDict. Prinsip panduannya adalah bahwa operasi yang tidak melibatkan tipe
movie2: Movie = {'title': 'Blade Runner', 'year': 1982}3 harus ditolak oleh pemeriksa tipe jika mungkin melanggar keamanan tipe runtime. Berikut adalah beberapa jenis pelanggaran keselamatan yang paling penting untuk dicegah
- Kunci yang diperlukan tidak ada
- Nilai memiliki jenis yang tidak valid
- Kunci yang tidak ditentukan dalam tipe TypedDict ditambahkan
Kunci yang bukan literal umumnya harus ditolak, karena nilainya tidak diketahui selama pemeriksaan tipe, dan dengan demikian dapat menyebabkan beberapa pelanggaran di atas. [ menggeneralisasi ini untuk mencakup nama akhir dan tipe literal. ]
Penggunaan kunci yang tidak diketahui keberadaannya harus dilaporkan sebagai kesalahan, bahkan jika ini tidak serta merta menghasilkan kesalahan jenis runtime. Ini sering kali merupakan kesalahan, dan ini dapat menyisipkan nilai dengan tipe yang tidak valid jika subtipe struktural menyembunyikan tipe item tertentu. Misalnya,
from typing import TypedDict class Movie[TypedDict]: name: str year: int_27 harus menghasilkan kesalahan pemeriksaan tipe jika
from typing import TypedDict class Movie[TypedDict]: name: str year: int13 bukan kunci yang valid untuk
class EmptyDict[TypedDict]: pass6 [yang dianggap sebagai tipe TypedDict]
Kunci tambahan yang disertakan dalam konstruksi objek TypedDict juga harus ditangkap. Dalam contoh ini, kunci
from typing import TypedDict class Movie[TypedDict]: name: str year: int_30 tidak ditentukan dalam
movie: Movie = {'name': 'Blade Runner', 'year': 1982}0 dan diharapkan menghasilkan kesalahan dari pemeriksa tipe
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_8
Pemeriksa tipe harus menolak operasi berikut pada objek TypedDict sebagai tidak aman, meskipun valid untuk kamus normal
- Operasi dengan kunci
from typing import TypedDict class Movie[TypedDict]: name: str year: int
8 sewenang-wenang [bukan literal string atau ekspresi lain dengan nilai string yang diketahui] umumnya harus ditolak. Ini melibatkan operasi destruktif seperti menyetel item dan operasi hanya-baca seperti ekspresi berlangganan. Sebagai pengecualian untuk aturan di atas,from typing import TypedDict class Movie[TypedDict]: name: str year: int
_33 danfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
34 harus diizinkan untuk objek TypedDict, untuk ekspresi arbitrerfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
35 dengan tipefrom typing import TypedDict class Movie[TypedDict]: name: str year: int
8. Motivasinya adalah ini aman dan dapat berguna untuk mengintrospeksi objek TypedDict. Tipe statisfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
33 harusfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
38 jika nilai stringfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
35 tidak dapat ditentukan secara statis from typing import TypedDict class Movie[TypedDict]: name: str year: int
18 tidak aman karena dapat menghapus kunci yang diperlukan, beberapa di antaranya mungkin tidak langsung terlihat karena subtipe struktural.from typing import TypedDict class Movie[TypedDict]: name: str year: int
41 juga tidak aman, bahkan jika semua kunci yang diketahui tidak diperlukan [from typing import TypedDict class Movie[TypedDict]: name: str year: int
42]from typing import TypedDict class Movie[TypedDict]: name: str year: int
43 harus ditolak kecualifrom typing import TypedDict class Movie[TypedDict]: name: str year: int
44 adalah kunci yang tidak diperlukan
Pemeriksa jenis memungkinkan membaca item menggunakan
from typing import TypedDict class Movie[TypedDict]: name: str year: int45 bahkan jika kunci
from typing import TypedDict class Movie[TypedDict]: name: str year: int13 tidak diperlukan, alih-alih membutuhkan penggunaan
from typing import TypedDict class Movie[TypedDict]: name: str year: int47 atau pemeriksaan
from typing import TypedDict class Movie[TypedDict]: name: str year: int48 eksplisit. Alasannya adalah bahwa melacak keberadaan kunci sulit diterapkan secara umum penuh, dan pelarangan ini dapat memerlukan banyak perubahan pada kode yang ada
Aturan pemeriksaan tipe yang tepat tergantung pada masing-masing pemeriksa tipe untuk memutuskan. Dalam beberapa kasus, operasi yang berpotensi tidak aman dapat diterima jika alternatifnya adalah menghasilkan kesalahan positif palsu untuk kode idiomatik
Pemeriksa tipe harus mengizinkan nama akhir [PEP 591] dengan nilai string untuk digunakan sebagai ganti literal string dalam operasi pada objek TypedDict. Misalnya, ini valid
movie: Movie = {'name': 'Blade Runner', 'year': 1982}_9
Demikian pula, ekspresi dengan tipe literal yang sesuai [PEP 586] dapat digunakan sebagai pengganti nilai literal
from typing import TypedDict class Movie[TypedDict]: name: str year: int0
Pemeriksa tipe hanya diharapkan untuk mendukung literal string aktual, bukan nama akhir atau tipe literal, untuk menentukan kunci dalam definisi tipe TypedDict. Selain itu, hanya literal boolean yang dapat digunakan untuk menentukan totalitas dalam definisi TypedDict. Motivasinya adalah untuk membuat deklarasi tipe mandiri, dan untuk menyederhanakan penerapan pemeriksa tipe
Untuk mempertahankan kompatibilitas mundur, pemeriksa tipe tidak boleh menyimpulkan tipe TypedDict kecuali cukup jelas bahwa ini diinginkan oleh pemrogram. Jika tidak yakin, jenis kamus biasa harus disimpulkan. Jika tidak, kode yang ada yang memeriksa jenis tanpa kesalahan dapat mulai menghasilkan kesalahan setelah dukungan TypedDict ditambahkan ke pemeriksa jenis, karena jenis TypedDict lebih terbatas daripada jenis kamus. Secara khusus, mereka bukan subtipe dari tipe kamus
Pemeriksa tipe mypy mendukung tipe TypedDict. Implementasi referensi dari komponen runtime disediakan dalam modul
from typing import TypedDict class Movie[TypedDict]: name: str year: int49. Implementasi aslinya ada di modul
from typing import TypedDict class Movie[TypedDict]: name: str year: int50
Beberapa ide yang diajukan ditolak. Serangkaian fitur saat ini tampaknya mencakup banyak hal, dan tidak jelas ekstensi mana yang diusulkan akan lebih berguna. PEP ini menentukan fitur dasar yang berpotensi diperpanjang nanti
Ini pada prinsipnya ditolak, karena tidak sesuai dengan semangat proposal ini
- TypedDict tidak dapat diperluas, dan hanya membahas kasus penggunaan tertentu. Objek TypedDict adalah kamus reguler saat runtime, dan TypedDict tidak dapat digunakan dengan kelas mirip kamus atau mirip pemetaan lainnya, termasuk subkelas dari
movie: Movie = {'name': 'Blade Runner', 'year': 1982}
8. Tidak ada cara untuk menambahkan metode ke tipe TypedDict. Motivasi di sini adalah kesederhanaan - Definisi tipe TypedDict dapat digunakan secara masuk akal untuk melakukan pengecekan tipe runtime kamus. Misalnya, mereka dapat digunakan untuk memvalidasi bahwa objek JSON sesuai dengan skema yang ditentukan oleh tipe TypedDict. PEP ini tidak menyertakan fungsi tersebut, karena fokus proposal ini hanya untuk pemeriksaan jenis statis, dan jenis lain yang sudah ada tidak mendukung ini, seperti yang dibahas di. Fungsionalitas tersebut dapat disediakan oleh pustaka pihak ketiga menggunakan modul pihak ketiga
from typing import TypedDict class Movie[TypedDict]: name: str year: int
52, misalnya - Tipe TypedDict tidak dapat digunakan dalam pemeriksaan ________33______7 atau
from typing import TypedDict class Movie[TypedDict]: name: str year: int
54. Alasannya mirip dengan mengapa pemeriksaan jenis runtime tidak didukung secara umum dengan banyak petunjuk jenis
Fitur-fitur ini ditinggalkan dari PEP ini, tetapi merupakan ekstensi potensial yang akan ditambahkan di masa mendatang
- TypedDict tidak mendukung penyediaan tipe nilai default untuk kunci yang tidak ditentukan secara eksplisit. Ini akan memungkinkan kunci sewenang-wenang untuk digunakan dengan objek TypedDict, dan hanya kunci yang disebutkan secara eksplisit yang akan menerima perlakuan khusus dibandingkan dengan tipe kamus yang normal dan seragam
- Tidak ada cara untuk menentukan secara individual apakah setiap kunci diperlukan atau tidak. Tidak ada sintaks yang diusulkan cukup jelas, dan kami berharap ada kebutuhan terbatas untuk ini
- TypedDict tidak dapat digunakan untuk menentukan jenis argumen
from typing import TypedDict class Movie[TypedDict]: name: str year: int
55. Ini akan memungkinkan membatasi argumen kata kunci yang diizinkan dan jenisnya. Menurut PEP 484, menggunakan tipe TypedDict sebagai tipefrom typing import TypedDict class Movie[TypedDict]: name: str year: int
55 berarti TypedDict valid sebagai nilai argumen kata kunci arbitrer, tetapi tidak membatasi argumen kata kunci mana yang harus diizinkan. Sintaksfrom typing import TypedDict class Movie[TypedDict]: name: str year: int
_57 telah diusulkan untuk ini
David Foster menyumbangkan implementasi awal tipe TypedDict ke mypy. Perbaikan implementasi setidaknya telah disumbangkan oleh penulis [Jukka Lehtosalo], Ivan Levkivskyi, Gareth T, Michael Lee, Dominik Miedzinski, Roy Williams dan Max Moroz