5 คะแนน โดย GN⁺ 2024-10-14 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • TypedDict ถูกแนะนำใน PEP-589 และถูกรวมเข้ามาใน Python 3.8 โดยหลักแล้วใช้สำหรับสร้าง type annotation ให้กับดิกชันนารี
  • แทนที่จะใช้ dataclass หรือ pydantic เพื่อแทนข้อมูลประเภท 'record' นั้น TypedDict ใช้ประโยชน์จากความยืดหยุ่นของดิกชันนารี จึงได้เปรียบในสถานการณ์ที่บางฟิลด์อาจหายไป
  • ตัวอย่างเช่น การนิยามคลาส Movie และกำหนดพจนานุกรมชนิด Movie ให้กับตัวแปร movie
class Movie(TypedDict):  
    title: str  
  
  
movie: Movie = {"title": "Avatar"}  

Non-totality

  • TypedDict รองรับแนวคิด non-totality ซึ่งใช้บอกได้ว่าฟิลด์บางตัวอาจหายไป มีประโยชน์เมื่อทำ HTTP PATCH endpoint
  • dataclass ไม่มีแนวคิดเรื่องฟิลด์ที่หายไป จึงอาจดูไม่ค่อยเป็นธรรมชาติ
  • ใน TypedDict สามารถตั้งค่า total=False เพื่อจัดการกรณีฟิลด์หายไปได้อย่างยืดหยุ่น
  • PEP-655 ทำให้สามารถระบุแต่ละฟิลด์ด้วย Required และ NotRequired ได้

ใช้ TypedDict กับ **kwargs

  • PEP-692 ทำให้สามารถใช้ TypedDict เพื่อระบุชนิดของ variable keyword arguments ได้
  • แม้การใช้ TypedDict อาจทำให้โค้ดดูยาวขึ้น แต่จะมีประโยชน์เมื่อสามารถนำกลับมาใช้ซ้ำในหลายฟังก์ชันได้
  • เมื่อใช้ร่วมกับ non-totality จะยิ่งแสดงจุดแข็งมากขึ้น
    • เช่น กรณีปรับแต่ง pytest.fixture แล้วส่งต่ออาร์กิวเมนต์บางส่วนแบบเดิม
  • สามารถทำพฤติกรรมคล้ายกันได้ด้วยค่า sentinel แต่ type annotation อาจดูฝืนธรรมชาติ

ใช้ TypedDict สำหรับ dependency injection

  • PEP-692 ทำให้ตรวจสอบประเภทได้เมื่อเรียกฟังก์ชันโดยใช้ TypedDict
  • มีประโยชน์ในสถานการณ์ที่ resource หลายตัวใช้ dependency บางส่วนร่วมกัน
  • นิยาม TypedDict ที่คล้ายกับการรวม kwargs ของ resource ทั้งหมดเข้าด้วยกัน
  • จากนั้นเขียน resource ใหม่ให้รับอาร์กิวเมนต์ตามต้องการ และทำ dependency injection ผ่าน TypedDict
  • ระบบชนิดข้อมูลช่วยตรวจสอบข้อผิดพลาดของอาร์กิวเมนต์หรือการตกหล่นระหว่างทำ dependency injection ได้
  • แม้การเปลี่ยน signature ของ resource จะไม่ใช่ทางเลือกที่ดีที่สุด แต่ก็ยังเป็นการเปลี่ยนแปลงที่เล็กกว่าการใช้ dependency injection framework
  • framework จำนวนมากยังไม่รองรับ static type checking

ความสามารถในอนาคต

  • PEP-728 จะทำให้สามารถนิยามชนิดของรายการเพิ่มเติม และนิยามดิกชันนารีแบบปิดที่ไม่ยอมรับรายการเพิ่มเติมได้
    • ช่วยให้นิยาม record type ได้แม่นยำยิ่งขึ้น
  • PEP-705 จะทำให้กำหนดรายการแบบอ่านอย่างเดียวได้ (ขึ้นอยู่กับช่วงเวลาที่ประกาศ อาจออกแล้วก็ได้)
    • รองรับสถานการณ์ที่อาจเกิดปัญหาจากการเปลี่ยนแปลงค่าแบบกลายพันธุ์ (ลบค่า) ระหว่าง TypedDict อื่น ๆ ที่ตามสัญชาตญาณควรเข้ากันได้

สรุปโดย GN⁺

  • TypedDict ได้เปรียบในสถานการณ์ที่บางฟิลด์อาจหายไป เพราะใช้ประโยชน์จากความยืดหยุ่นของดิกชันนารีได้
  • TypedDict เป็นตัวเลือกที่ยืดหยุ่นกว่าโครงสร้างข้อมูลแบบอื่นอย่าง dataclass หรือ pydantic
    • ควรเลือกใช้เครื่องมือให้เหมาะกับโดเมน แต่ก็ควรจำข้อดีของ TypedDict ไว้ด้วย

2 ความคิดเห็น

 
ilotoki0804 2024-10-15

ถ้าข้อมูลมาจากภายนอกในรูปแบบ JSON หรือมีการ export ออกไปนอก Python บ่อย ๆ การใช้ TypedDict จะเหมาะสม แต่ถ้าไม่ใช่ ขอแนะนำให้ใช้ dataclass หรือ NamedTuple ที่มีโครงสร้างแทน

 
GN⁺ 2024-10-14
ความคิดเห็นจาก Hacker News
  • คนที่ชอบ dynamic typing กำลังตระหนักถึงความสำคัญของระบบ type มากขึ้นเรื่อย ๆ

    • ระบบ type ที่ดีกว่าย่อมเหนือกว่าระบบ type ที่แย่กว่า
  • เหตุผลที่ใช้ dataclass(slots=True) แทน TypedDict

    • การเข้าถึง attribute เร็วกว่า จึงทำให้โค้ดเร็วกว่า
    • คลาสแบบ slots ใช้ RAM น้อยกว่า และกดดัน L1 cache น้อยกว่า จึงทำให้โค้ดเร็วกว่า
    • เวลาเข้าถึง attribute ใช้ .foobar แทน ["foobar"] จึงไม่ทรมานข้อมือเท่า
    • ถ้าพิมพ์ชื่อ attribute ผิด จะเกิด runtime error
  • ถ้าไม่มีระบบที่บังคับใช้ type แล้ว TypedDict ก็แทบไม่มีบทบาทอะไร

    • ต่อให้เก็บค่าผิดไว้ใน property ที่ใส่ annotation เป็นสตริง Python ปกติก็ไม่ห้ามและไม่เตือน
    • ถ้าต้องการบังคับใช้ type จริง ๆ ต้องใช้เครื่องมืออย่าง Pydantic
  • ชื่อเรื่อง "thank you think" ฟังดูหยาบคายเกินไป

    • "than i thought" อ่านลื่นกว่ามาก
  • ในประโยคเกี่ยวกับการสมัครสมาชิก ความหมายของ "None" ไม่ชัดเจน

    • ไวยากรณ์ซับซ้อนจนเข้าใจได้ยาก
  • ประสบการณ์ส่วนตัวกับ TypedDict

    • ใช้ TypedDict ใส่ annotation ให้ dicts เพื่อให้อ่านโค้ดง่ายขึ้น
    • ช่วยลดเวลาที่ต้องไล่ตาม code path
    • ยังต้องพัฒนาทักษะการเขียนโค้ดอีกมาก แต่สำหรับแอปที่ใช้ dict เยอะ นี่เป็นทางออกที่ดี
  • ความสามารถของ TypedDict นั้นดี แต่ syntax สำหรับประกาศค่อนข้างซับซ้อน