Gambaran
Pertanyaannya telah diatasi. Namun, jawaban ini menambahkan beberapa contoh praktis untuk membantu dalam pemahaman dasar kacamata.
Apa sebenarnya kelas data python dan kapan waktu terbaik untuk menggunakannya?
- generator kode : menghasilkan kode boilerplate; Anda dapat memilih untuk menerapkan metode khusus di kelas reguler atau meminta dataclass menerapkannya secara otomatis.
- wadah data : struktur yang menyimpan data (misalnya tupel dan dikt), seringkali dengan titik, akses atribut seperti kelas,
namedtuple
dan lainnya .
"dapat dinamai namesuple dengan [s] default"
Inilah yang dimaksud frasa terakhir:
- bisa berubah : secara default, atribut dataclass dapat dipindahkan. Secara opsional Anda dapat membuatnya tidak berubah (lihat Contoh di bawah).
- namedtuple : Anda telah bertitik, akses atribut seperti
namedtuple
kelas biasa atau.
- default : Anda dapat menetapkan nilai default ke atribut.
Dibandingkan dengan kelas umum, Anda lebih menghemat mengetik kode boilerplate.
fitur
Ini adalah gambaran umum fitur-fitur dataclass (TL; DR? Lihat Tabel Ringkasan di bagian selanjutnya).
Apa yang kau dapatkan
Berikut adalah fitur-fitur yang Anda dapatkan dari kacamata standar.
Atribut + Representasi + Perbandingan
import dataclasses
@dataclasses.dataclass
#@dataclasses.dataclass() # alternative
class Color:
r : int = 0
g : int = 0
b : int = 0
Default ini disediakan dengan secara otomatis mengatur kata kunci berikut untuk True
:
@dataclasses.dataclass(init=True, repr=True, eq=True)
Apa yang bisa Anda nyalakan
Fitur tambahan tersedia jika kata kunci yang sesuai diatur ke True
.
Memesan
@dataclasses.dataclass(order=True)
class Color:
r : int = 0
g : int = 0
b : int = 0
Metode pemesanan sekarang diterapkan (operator kelebihan beban:) < > <= >=
, mirip dengan functools.total_ordering
dengan uji kesetaraan yang lebih kuat.
Hashable, Mutable
@dataclasses.dataclass(unsafe_hash=True) # override base `__hash__`
class Color:
...
Meskipun objek berpotensi berubah (mungkin tidak diinginkan), hash diimplementasikan.
Hashable, Immutable
@dataclasses.dataclass(frozen=True) # `eq=True` (default) to be immutable
class Color:
...
Hash sekarang diimplementasikan dan mengubah objek atau menugaskan ke atribut tidak diizinkan.
Secara keseluruhan, objek tersebut dapat di hash jika salah satu unsafe_hash=True
atau frozen=True
.
Lihat juga tabel logika hashing asli dengan detail lebih lanjut.
Apa yang tidak Anda dapatkan
Untuk mendapatkan fitur berikut, metode khusus harus diterapkan secara manual:
Membongkar
@dataclasses.dataclass
class Color:
r : int = 0
g : int = 0
b : int = 0
def __iter__(self):
yield from dataclasses.astuple(self)
Optimasi
@dataclasses.dataclass
class SlottedColor:
__slots__ = ["r", "b", "g"]
r : int
g : int
b : int
Ukuran objek sekarang berkurang:
>>> imp sys
>>> sys.getsizeof(Color)
1056
>>> sys.getsizeof(SlottedColor)
888
Dalam beberapa keadaan, __slots__
juga meningkatkan kecepatan membuat instance dan mengakses atribut. Juga, slot tidak memungkinkan penetapan standar; jika tidak, a ValueError
dinaikkan.
Lihat lebih banyak di slot di posting blog ini .
Tabel Ringkasan
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Feature | Keyword | Example | Implement in a Class |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Attributes | init | Color().r -> 0 | __init__ |
| Representation | repr | Color() -> Color(r=0, g=0, b=0) | __repr__ |
| Comparision* | eq | Color() == Color(0, 0, 0) -> True | __eq__ |
| | | | |
| Order | order | sorted([Color(0, 50, 0), Color()]) -> ... | __lt__, __le__, __gt__, __ge__ |
| Hashable | unsafe_hash/frozen | {Color(), {Color()}} -> {Color(r=0, g=0, b=0)} | __hash__ |
| Immutable | frozen + eq | Color().r = 10 -> TypeError | __setattr__, __delattr__ |
| | | | |
| Unpacking+ | - | r, g, b = Color() | __iter__ |
| Optimization+ | - | sys.getsizeof(SlottedColor) -> 888 | __slots__ |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
+ Metode-metode ini tidak dihasilkan secara otomatis dan membutuhkan implementasi manual dalam sebuah dataclass.
* __ne__
tidak diperlukan dan karenanya tidak diterapkan .
Fitur tambahan
Pasca inisialisasi
@dataclasses.dataclass
class RGBA:
r : int = 0
g : int = 0
b : int = 0
a : float = 1.0
def __post_init__(self):
self.a : int = int(self.a * 255)
RGBA(127, 0, 255, 0.5)
# RGBA(r=127, g=0, b=255, a=127)
Warisan
@dataclasses.dataclass
class RGBA(Color):
a : int = 0
Konversi
Ubah dataclass menjadi tuple atau dict, secara rekursif :
>>> dataclasses.astuple(Color(128, 0, 255))
(128, 0, 255)
>>> dataclasses.asdict(Color(128, 0, 255))
{r: 128, g: 0, b: 255}
Keterbatasan
Referensi
- Pembicaraan R. Hettinger tentang Dataclasses: Pembuat kode untuk mengakhiri semua pembuat kode
- Pembicaraan T. Hunner tentang Kelas yang Lebih Mudah: Kelas Python Tanpa Semua Cruft
- Dokumentasi Python tentang detail hashing
- Nyata Python panduan tentang The Ultimate Guide to Kelas data dengan Python 3.7
- Posting blog A. Shaw pada tur singkat kelas data Python 3.7
- E. gudang github Smith pada dataclasses
namedtuple
s tidak dapat diubah dan tidak dapat memiliki nilai default untuk atribut, sedangkan kelas data bisa berubah dan dapat memilikinya.