
dataclass(slots=True, kw_only=True): ล็อกฟิลด์และบังคับคีย์เวิร์ด
น้องกายEngineering
เคยพิมพ์ชื่อฟิลด์ผิดแล้วอ็อบเจ็กต์เงียบๆ รับแอตทริบิวต์ใหม่ไหม ผมเคย จนเปิด slots=True
ตามเอกสาร dataclasses พารามิเตอร์ slots=True ทำให้คลาสใช้ __slots__ แทน __dict__ ทั่วไป จึงกันการสร้างแอตทริบิวต์นอกที่ประกาศ ส่วน kw_only=True บังคับส่งค่าเป็นคีย์เวิร์ดตอนสร้างอินสแตนซ์
เลือกเมื่อไหร่
- slots=True: ต้องการกัน typo แอตทริบิวต์ และลดหน่วยความจำต่ออ็อบเจ็กต์จำนวนมาก
- kw_only=True: ฟิลด์หลายตัวชนิดคล้ายกัน กลัวสลับตำแหน่งตอนเรียก
- ระวัง: คลาสที่มี
slots=Trueใช้กับมัลติเพิลอินเฮริแตนซ์บางแบบต้องอ่านข้อจำกัดในเอกสารก่อน
from dataclasses import dataclass
@dataclass(slots=True, kw_only=True)
class Point:
x: float
y: float
label: str = "origin"
p = Point(x=1.5, y=2.0, label="A")
assert p.x == 1.5 and p.label == "A"
try:
Point(1.5, 2.0)
raise AssertionError("positional should fail with kw_only")
except TypeError:
pass
try:
p.z = 3
raise AssertionError("slots should block new attrs")
except AttributeError:
pass
print("ok")
Recap
- เปิด
slots=Trueเมื่ออยากกันแอตทริบิวต์เผลอๆ และประหยัดหน่วยความจำ - เปิด
kw_only=Trueเมื่อลำดับอาร์กิวเมนต์ทำให้สับสนง่าย - อ่านข้อจำกัด inheritance ในเอกสารก่อนใช้ร่วมกับคลาสเก่า
- เขียนเทสต์สั้นๆ ว่าการสร้างแบบตำแหน่งและแอตทริบิวต์แปลกยังถูกปฏิเสธ