Penjelasan Beranotasi Simon Willison tentang Dataklasses David Beazley
David Beazley di Twitter:
Jadi, saya baru saja menerbitkan putaran jahat yang nikmat ini di kelas data. Ini kecil dan kelas yang dihasilkan mengimpor sekitar 15-20 lebih cepat daripada kelas data. https://github.com/dabeaz/dataklasses
Saya memutuskan untuk membuat versi kode aslinya yang beranotasi berat untuk mencari tahu sendiri cara kerjanya.
"x", "y") def __init__ (diri sendiri, x, y): diri sendiri.x=xdiri sendiri.y=y def __repr__( diri sendiri): kembalif"Koordinat({diri sendiri.x!r}, {diri sendiri.y!R})"def__eq__(diri sendiri, lainnya): jikasendiri.__kelas__adalahlainnya. __kelas__: kembali (diri sendiri,x, diri sendiri.y,) == (lainnya.x , lainnya.y,) kalau tidak: kembaliTidak Diimplementasikan
Trik kunci: pembuatan kode
Kunci untuk memahami cara kerja kode adalah dengan memahami bahwa itu menggunakan pembuatan kode. David mengintrospeksi properti kelas beranotasi, dari kelas itu sendiri dan superclass mana pun, lalu menghitung jumlahnya. Dia kemudian menghasilkan metode yang terlihat seperti ini:
def__init__(diri sendiri, _0, _1): sendiri._0=_0diri sendiri ._1=_1
Kemudian gunakan func.__code__.replace(co_names=repl_co_names, co_varnames=repl_co_varnames) metode untuk mengganti nama itu _0 dan _1 variabel kembali ke x dan y.
Saya belum mengerti mengapa dia melakukan ini sebagai lawan menghasilkan kode menggunakan x dan y secara langsung. Saya akan memperbarui ini dengan penjelasan setelah saya menemukannya!
Pembaruan: Jacob Kaplan-Moss menjelaskannya di sini!
Itu benar-benar liar trik inti dari ini, dan apa yang membuatnya cepat:
bytecode untuk
__init__(sendiri, x, y)
persis sama dengan bytecode untuk __init__(self, foo, bar)!
Jadi itu berarti Dave dapat men-cache kode yang dihasilkan untuk "any __init__ berfungsi dengan dua argumen" dan kemudian
re -gunakan kode yang sama persis untuk 2-arity selanjutnya __init__s!
Salinan beranotasi saya
Pertama, termasuk pesan hak cipta seperti yang dipersyaratkan oleh pesan hak cipta:
# dataklasses.py # # https://github.com/dabeaz/dataklasses## Pengarang : David Beazley (@dabeaz).# http://www.dabeaz.com## Hak cipta (C) 2021-2022. ## Izin diberikan untuk menggunakan , salin, dan ubah kode ini di any # cara selama pesan hak cipta dan disclaimer ini tetap ada # kode sumber. Tidak ada garansi. Coba gunakan kode untuk # lebih baik.
Anotasi saya dimulai di sini (Saya juga menjalankannya hingga Hitam).
__semua__=# Ini memastikan "dari impor dataklasses *" hanya akan mengimpor simbol dataklass darifungsiimpor
lru_cache
,
mengurangi # Dekorator ini mengambil fungsi yang mengembalikan kode sumber Python dan mengkompilasinya # itu menjadi fungsi Python. Jadi jika func(fields) mengembalikan string berikut: ## def __init__(sendiri, a): # diri.a=a# # Nilai yang dikembalikan adalah itu fungsi yang dikompilasi. Dengan beberapa penyempurnaan.defkodegen(fungsi): # Ini menyimpan hasil jadi jika Anda melewati numfields yang sama tidak perlu # melakukan pekerjaan yang sama dua kali .## Ini adalah pengoptimalan kinerja utama untuk kode ini – ini berarti # kode yang dihasilkan sama dapat digunakan kembali untuk setiap kelas yang memiliki kesamaan # jumlah argumen!@lru_cachedefmake_func_code(numfields) : # numfields di len(fields) nama= [f”_{n}“forninrange(numfields)] # nama sekarang [“_0”, “_1”, “_2”] tergantung pada numfields # # Kami memanggil func() dengan daftar nama itu dan exec() the# mengembalikan kode sumber. Argumen ketiga untuk exec() adalah# locals() – ini adalah kamus yang fungsi exec() # akan diisi dengan simbol baru. ## Kami menggunakan d:={} operator walrus di sini sehingga kami dapat# lihat kamus itu dengan nama d sebentar lagi.eksekutif(
func(
nama), global(), d := {}) # d.popitem() kembali pasangan (kunci, nilai) pertama di # kamus. Kita tahu bahwa kamus locals() # hanya akan memiliki satu simbol di dalamnya, karena# kita sekarang bahwa kode dikembalikan oleh fungsi(nama) saja# mendefinisikan satu fungsi. Jadi ini mengembalikan nilai# dari item pertama di locals(), function objectkembalid.popitem
()[1] # Dekorasi ini() adalah nilai kembalian dari dekorator,# yang artinya kode berikut: # # @codegen# def make__init__(bidang): # # …# Mengubah make__init__ menjadi fungsi yang ditentukan oleh dekorasi()defdekorasi(bidang): # Seperti yang ditunjukkan di atas, ini menggunakan exec() untuk mengkompilasi dan mengembalikan # badan fungsi yang dibuat menggunakan kode sumber yang dihasilkan fungsi=make_func_code(
len(
bidang)) # Tapi ingat: karena kami men-cache dan menggunakan kembali badan metode, ini memiliki # jelek _0, _1 parameter dan variabel yang ingin kita buat lebih bagus. # co_names: tuple nama selain argumen dan fungsi lokalco_names=fungsi.__code__.co_name s# Untuk contoh Koordinat, nama_bersama=(“_0”, “_1”)# co_varnames: tuple nama argumen dan variabel lokal co_varnames = fungsi.__kode__.co_varnames# Untuk contoh Koordinat, co_varnames=(“self”, “_0”, “_1” )# Kami akan mengganti co_names dan co_varnames dengan modifikasi# versi – jadi kita perlu membuat dua tupel pengganti untuk mereka. # # start :=co_names.index(“_0”) menggunakan operator walrus untuk keduanya# cari tahu indeks berbasis 0 dari simbol _0 dan menetapkannya ke s# # Kami menggunakan (*a, *b, *c) untuk membuat tupel baru yang merupakan hasil dari # menggabungkan ketiga tupel input tersebut.repl_co_names
= (
# Iris semuanya dalam co_names hingga simbol _0 pertama
*co_names[start+len(fields) :],
# Kemudian masukkan bidang, yang merupakan properti kelas beranotasi *bidang, # Sekarang semuanya dalam co_names berikut *co_names[start+len(fields) :], ) # Untuk Koordinat ini sekarang (“x”, “y”)repl_co_varnames= ( # Kami hanya memodifikasi co_varnames jika _0 adalah salah satunya, jika tidak # kami membiarkannya tidak berubah. ( *co_varnames[: (start:=co_varnames.index(“_0”))], *
bidang,
*
co_varnames[start+len(fields) :], ) jika“_0”dico_varnameselseco_varnames ) # Untuk Koordinat ini sekarang (“self”, “x”, “y”)# type(func) mengembalikan objek internal Python yang disebut “fungsi”# yang dapat dipanggil dan memiliki tanda tangan fungsi ini: ## fungsi(kode, global, nama=Tidak ada, argdefs=Tidak ada, penutupan=Tidak ada)## Ini menciptakan objek fungsi baru kembaliTipe(fungsi)( # func.__code__.replace docstring mengatakan: # “Kembalikan salinan objek kode dengan nilai baru untuk bidang yang ditentukan” # Jadi kami menulis ulang co_names dan co_varnames di sini fungsi.__kode__.mengganti(co_names=
repl_co_names
, co_varnames=repl_co_varnames ), fungsi.__globals__, ) kembalidekorasidefall_hints(cls): # Ini mengintrospeksi kelas untuk menemukan semua anggota kelas beranotasi # Dalam Koordinat cas e ini mengembalikan {‘x’: , ‘y’: } # # “x” untuk lambda itu dimulai sebagai {} kamus kosong itu dan setiap kali# adalah kamus dengan hal-hal baru yang ditambahkan ke dalamnya.## reversed(Coordinates.__mro__) loop melalui setiap superclass saat ini # kelas, dimulai dari “objek”.## Jadi lambda dipanggil melawan setiap superclass secara bergantian, dan setiap kali itu# membaca bidang __annotations__, jika tersedia. # # Coordinates.__annotations__ mengembalikan {‘x’: int, ‘y’: int}## dict1 | dict2 di Python mengembalikan dict baru yang menggabungkan dua sebelumnya ## Jadi fungsi ini mengembalikan kamus gabungan dari __annotations__ from# setiap kelas dalam hierarki superclass. kembali kurangi ( lambdax, y: x|
getattr
(y, “__annotations__”, {}),
terbalik
(cls.__mro__), {} ) # Berikutnya adalah fungsi yang menghasilkan metode yang berbeda. Ingat mereka lulus # bidang yang adalah {‘x’: , ‘y’:
} @codegendefmake__init__(bidang): # Memanggil “,”.join(dict) bergabung saja kunci kamus itukode=“def __init__(sendiri, “+“,”.Ikuti(
bidang)
+ “): n” # Jadi di sini kita memiliki: # def __init__ (sendiri, x, y): kembalikode+“n“ .Ikuti(f” diri sendiri.{nama}={nama}n“untuknamadibidang)
# Ini menambahkan:
# self.x=x # self.y=y@kodegendefmake__repr__(bidang): kembali ( “def __repr__(self): n“# type(self).__name__ memberi kita nama kelas: “Koordinat”‘ return f”{type(self).__name__}(‘# Ini memberi kita {self.x!r}, {self.y! r} yang dalam f-string# memberi kami __repr__() versi properti objek tersebut +“, “.Ikuti(“{diri sendiri.”+nama+ “!R}” untuknamadibidang) +‘)”n‘ ) # Jadi ini menghasilkan: # def __repr__(self): # return f”Koordinat({self.x!r}, {self.y!r})” @kodegendefmake__eq__(bidang): selfvals =“,”.Ikuti(f”diri sendiri.{nama}“untuknamadibidang ) lain-lain=“,,”.Ikuti(f”lainnya.{
nama}“
untuk namadibidang ) kembali ( “def __eq__(diri sendiri, orang lain): n“” jika self.__class__ adalah other.__class__: n“f” kembali ({selfvals},)==({lainnya S},)n“ ” kalau tidak: n“” return NotImplementedn“ ) # Ini menghasilkan: # def __eq__(diri sendiri, orang lain): # jika self.__class__ adalah yang lain.__class__: # return (self,x, self.y,)==(other.x, other.y)# kalau tidak: # return NotImplemented@kodegendefmake__iter__(bidang): kembali“def __iter__(sendiri): n” +“n“.Ikuti( f” menghasilkan diri sendiri.{ nama}“untuk namadibidang ) @kodegendefmake__hash__(bidang): self_tuple=“(“+“,,”.Ikuti(f”diri.{nama}” untuknamadi
cls): bidang=all_hints(cls) # bidang sekarang {‘x’: , ‘y’: }clsdict=vars(cls) # clsdict terlihat seperti ini: # {‘__module__’: ‘__main__’,
# '__annotations__': {'x': , 'y': },
# ‘__dict__’: ,# ‘__weakref__’: , # ‘__doc__’: Tidak ada} # # Tujuan dari fungsi ini terutama untuk menambahkan __init__ dan# __repr__ dan __eq__ metode, tetapi hanya jika belum didefinisikan jikabukan“__init__”diclsdict:
(bidang) # Tidak yakin mengapa ini dikomentari sekarang: # jika tidak ‘__iter__’ di clsdict: cls.__iter__=make__iter__(fields) # jika tidak ‘__hash__’ di clsdict: cls.__hash__=make__hash__(fields)cls.__match_args__=bidang# Ini terkait dengan pengetikan struktural Python: # https://www.python.org/dev/peps/pep-0622/#special-attribute-match-argskembali cl s# Contoh penggunaanjika__nama__ ==“__utama__”: @dataklass kelasKoordinat: x: inty: int
Dibuat 2021-12-19T20:30:57-08:00, diperbarui 2021-12-19T21:38:45-08:00 · Riwayat · Edit
Soal Ujian Akhir Semester Sejarah Indonesia Kelas 11… Sebagai seorang siswa kelas 11, kamu pasti sudah tidak asing lagi dengan mata pelajaran sejarah Indonesia. Nah, salah satu bagian penting dalam pembelajaran sejarah Indonesia adalah ujian akhir semester (UAS).…
Tanya HN: Aku Sangat Kesepian Tanya HN: Aku Sangat Kesepian 23 poin oleh DevToRecruiter 23 menit yang lalu | sembunyikan | masa lalu | favorit | 21 komentar Saya tidak tahu apakah ini tempat yang…
Colby Covington memprediksi pengajuan 'Rekor… Colby Covington telah membangun pertarungan dengan mantan juara kelas ringan sementara UFC Dustin Poirier bahkan sebelum dia mengalahkan Jorge Masvidal awal bulan ini. Tetapi dalam sebuah wawancara baru-baru ini, Covington…
Buku Sejarah Indonesia Kelas XI PDF: Perjalanan… Memudahkan Belajar Sejarah Indonesia: Unduh Buku Sejarah Indonesia Kelas XI PDF Sekarang! Buku sejarah indonesia kelas xi pdf merupakan referensi yang penting bagi para siswa kelas XI SMA yang mempelajari…
Kunci Jawaban PTS Genap Sejarah Indonesia Kelas 10:… Soal PTS Genap Sejarah Indonesia Kelas 10: Uji Pemahamanmu tentang Perjalanan Bangsa Indonesia! Sebagai siswa kelas 10, kamu tentu sudah tidak asing lagi dengan mata pelajaran Sejarah Indonesia. Nah, untuk…
Kuis Sejarah Indonesia Kelas 10 Semester 2: Tantang… Tahukah kamu bahwa belajar sejarah Indonesia kelas 10 semester 2 bisa menjadi menyenangkan dan interaktif? Dengan Quizizz Sejarah Indonesia Kelas 10 Semester 2, kamu bisa menguji pengetahuanmu tentang sejarah Indonesia…
Kamaru Usman mengatakan dia mengajukan petisi ke UFC… Apa yang kamu lakukan jika kamu ingin menjadi juara dua divisi tetapi temanmu memegang sabuk di kelas berat di atas? Mengapa, Anda naik dua kelas berat. Usman mengatakan dia tertarik…
Menyelami Sejarah Indonesia: Perjalanan Bangsa yang… Pernahkah kamu merasa kesulitan dalam menjawab soal-soal sejarah Indonesia kelas 10? Apakah kamu merasa tidak memahami materi yang diajarkan di kelas? Jika iya, kamu tidak sendirian. Banyak siswa yang merasa…
Jon Jones bereaksi terhadap rekaman penangkapan… Awal minggu ini, rekaman bodycam petugas polisi dari mantan juara kelas berat ringan UFC Jon Jones yang ditangkap di Las Vegas pada bulan September dirilis. Rekaman itu menunjukkan Jones yang…
Perawatan diri dengan anggaran terbatas: 5 ide… Hidup sepertinya selalu ramai dengan acara, kumpul-kumpul, dan kumpul keluarga, tapi jangan lupa luangkan waktu untuk menjaga kesehatan diri dan utamakan perawatan diri.Berinvestasi pada diri sendiri tidak harus melibatkan hari…
Paulo Costa merobek 'macho palsu' Sean… 18 Maret 2022 11:20 ET Paulo Costa memiliki beberapa pilihan kata untuk Sean Strickland setelah dia mengubah nadanya pada pertarungan potensial. Strickland (25-3 MMA, 12-3 UFC) memanggil Costa pada November…
Inilah Cara Membuat Seseorang Terbuka kepada Anda… Pernahkah Anda berbicara dengan pelanggan, kolega, karyawan, atau teman, dan berharap Anda bisa membuat mereka terbuka dan memberi tahu Anda apa yang sebenarnya mereka pikirkan? Meskipun Anda tidak dapat—dan tidak…
Miesha Tate mempertimbangkan untuk pindah ke divisi… Mantan juara kelas bantam wanita UFC Miesha Tate sedang mempertimbangkan untuk pindah kelas berat ke divisi kelas terbang. Tate keluar dari masa pensiunnya pada bulan Juli dengan mengalahkan Marion Reneau…
Charles Oliveira menanggapi seruan Conor McGregor:… Mantan juara dua divisi Conor McGregor menanyakan tanggal berapa dia melawan juara kelas ringan Charles Oliveira pada hari Senin, dan Oliveira menjawab. “Jadi tanggal berapa saya melawan Oliveira,” McGregor memposting…
Tonton: Colby Covington mengatakan dia membiarkan… Setelah bertahun-tahun mengamuk dan bermusuhan, itu adalah Kekacauan yang memerintah tertinggi di Las Vegas pada Sabtu malam. Colby Covington membawa tingkat penutupan perseteruan selama bertahun-tahun dengan mantan teman dan mitra…
Kartu utama resmi diumumkan untuk UFC 271, Derrick… Melalui: @ChadSonnen di Twitter The Ultimate Fighting Championship telah mengumumkan kartu utama untuk UFC 271 dengan Derrick Lewis vs Tai Tuivasa berfungsi sebagai acara utama. Bulan depan di Houston, UFC…
7 Cara Meningkatkan Kepercayaan Diri Anda Anda tidak dapat menang sebagai pengusaha atau pemilik bisnis tanpa kepercayaan penuh pada kemampuan Anda sendiri, serta pada solusi dan model bisnis Anda. Sebagai angel investor di startup, saya selalu…
Hidup dengan kecemasan membantu saya menyadari bahwa… Seperti yang diceritakan kepada Nicole Audrey SpectorSaya akan bangun menangis pada jam 3 pagi dan merasakan langit-langit turun dan dinding menutup saya. Tenggorokan dan dadaku terasa sesak. Tidak ada jalan…
Jelajahi Sejarah Indonesia Kelas 10: Kisah Bangsa… Perjalanan Sejarah Indonesia Melalui Cover Buku yang Menarik Sebagai siswa SMA kelas 10, mempelajari sejarah Indonesia menjadi salah satu mata pelajaran yang wajib diikuti. Namun, tidak sedikit siswa yang merasa…
Israel Adesanya, Robert Whittaker binatang yang sama… 10 Februari 2022 10:00 malam ET HOUSTON – Israel Adesanya dan Robert Whittaker tampaknya tidak terlalu menyukai satu sama lain, tetapi pada konferensi pers UFC 271 Kamis , rasa hormat…
UFC Vegas 41 Face-off: Paulo Costa dan Marvin… Setelah penimbangan resmi UFC Vegas 41 hari Jumat di UFC Apex di Las Vegas, para petarung yang bertanding dalam kartu pertarungan berhadapan dengan lawan mereka. Pesaing kelas menengah Paulo Costa…
3 Rahasia Mengejutkan dari Kepemimpinan Cerdas (Yang… Setelah melatih dan melatih para pemimpin selama dua dekade, saya dapat menyatakan ini dengan percaya diri: Ada perilaku kepemimpinan yang jelas yang berdampak positif bagi bisnis untuk tumbuh hingga potensi…
Kunci Jawaban Sejarah Indonesia Kelas 10 Semester 2:… Bagi para pelajar Sekolah Menengah Atas (SMA) kelas X, kini tidak perlu lagi khawatir dalam menghadapi ulangan harian atau ujian semester untuk mata pelajaran sejarah Indonesia. Dalam artikel ini, tersedia…
Buku Elektronik Sejarah Indonesia Kelas 10 Erlangga:… Di era digital ini, akses informasi semakin mudah dan cepat. Namun, tidak semua informasi yang tersedia akurat dan terpercaya. Hal ini juga berlaku untuk buku pelajaran sejarah Indonesia kelas 10.…
Setelah 3 Bulan, Saya Menyadari Pelacakan Waktu… Saya mendengarkan banyak podcast produktivitas, dan salah satu hal yang sering muncul adalah pelacakan waktu. Idenya adalah bahwa orang menggunakan aplikasi dan layanan yang memungkinkan mereka melacak berapa banyak waktu…
Bagaimana Orang yang Cerdas Secara Emosional… "Apakah kamu marah padaku?"Kata-kata istriku memotong dalam-dalam. Mereka terluka karena dia benar: Saya terdengar marah.Masalahnya adalah salah satu yang dihadapi banyak orang sejak pandemi Covid-19 pertama kali menyerang lebih dari…
Bagaimana Menjadi Pelatih Karir Anda Sendiri Pembinaan membantu kita memahami diri kita sendiri, menemukan pilihan baru, dan melepaskan diri dari kemandekan, tetapi kesempatan untuk menghabiskan waktu dengan pelatih yang memenuhi syarat hanya tersedia bagi beberapa individu…
Menguak Jejak Masa Lalu Indonesia: Emodul Sejarah… Belajar Sejarah Indonesia Kelas 12 dengan Emodul Interaktif dan Menyenangkan Apakah Anda merasa kesulitan mempelajari sejarah Indonesia kelas 12? Apakah Anda merasa materi yang diajarkan terlalu berat dan sulit dipahami?…
Orang dengan Kecerdasan Emosional Menggunakan Trik… Ben dan Amy tidak saling mengenal, tetapi mereka berdua baru saja kehilangan pekerjaan. Awalnya, mereka berdua hancur. "Apa yang akan saya lakukan sekarang?" mereka berdua bertanya. Mereka masing-masing tertidur, berenang…
Fakta Mencengangkan: Rahasia Penting Sejarah… Soal Sejarah Indonesia Kelas 10 Semester 2 dan Jawabannya Hai, para pelajar kelas 10! Pastinya sudah tidak sabar ingin mengetahui materi sejarah Indonesia semester 2, kan? Nah, dalam postingan ini,…