นากกายสีมิ้นต์ล็อกลิ้นชักการ์ดคีย์บนโต๊ะมิ้นต์ให้เหลือเฉพาะช่องที่อนุญาต

Python 3.15 PEP 728: TypedDict ปิดหรือพิมพ์ extra items ได้แล้ว

น้องกายEngineering

TypedDict เดิมบอกชนิดของคีย์ที่รู้จักได้ดี แต่คีย์ส่วนเกินยังหลุดผ่าน structural typing ได้ง่าย

PEP 728 สถานะ Final สำหรับ Python 3.15 เพิ่มสองคลาสพารามิเตอร์

  • extra_items=T — อนุญาตคีย์อื่นที่ค่าต้องเข้ากับ T และถือเป็น non-required
  • closed=True — ไม่อนุญาตคีย์อื่น (เทียบเท่า extra_items=Never)

ใช้พร้อมกันไม่ได้ตอนประกาศ

ทำไมผมสนใจ

เวลาแคบชนิดด้วย in เช็กคีย์ เช่น แยก Movie กับ Book ด้วยคีย์ author แบบเดิมยังแคบไม่ได้เพราะ Movie อาจมี author แอบอยู่

TypedDict แบบปิดช่วยให้ type checker แคบชนิดได้สมเหตุสมผลกว่า และทำให้ .items() / .values() อนุมานชนิดได้ละเอียดขึ้น

อีกเคสคือ **kwargs: Unpack[SomeTypedDict] จาก PEP 692 ที่อยากอนุญาตคีย์เพิ่มแบบมีชนิด

ตัวอย่างแนวคิดจากสเปก

ตัวอย่างด้านล่างเป็นส่วนย่อจากสเปก ไม่ได้รันเป็นโมดูลเดี่ยว

class Movie(TypedDict, extra_items=bool):
    name: str

a: Movie = {"name": "Blade Runner", "novel_adaptation": True}  # OK
# year: int จะไม่ผ่านถ้า extra_items เป็น bool

หรือปิดสนิทด้วยตัวอย่างส่วนย่อนี้

class ClosedMovie(TypedDict, closed=True):
    name: str

closed และ extra_items สืบทอดได้ตามกฎใน PEP รวมถึงกรณี ReadOnly ที่ subclass แคบ extra ได้

Recap

  • ใช้ closed=True เมื่อโครงสร้างต้องเป๊ะ
  • ใช้ extra_items=T เมื่อรู้ชนิดของคีย์ส่วนเกิน
  • อย่าใส่ทั้งสองพารามิเตอร์พร้อมกัน
  • อ่าน PEP 728 ก่อนรีแฟกเตอร์ TypedDict ในโค้ดเบสใหญ่