تكرار السؤال: …
الإجابة المختصرة
ركّز الأنواع الدقيقة على الواجهات العامة وحدود النظام (دوال الموديول العامة، أنواع الـ domain، الـ protocols)، واترك المتغيرات المحلية للاستنتاج التلقائي.
الشرح
أفضل annotation هي التي توضح عقدًا أو invariant يستفيد منه القارئ والأداة: ماذا تقبل الدالة العامة وماذا تعيد، وأين قد تظهر None. استخدم NewType للتمييز بين معرفات من نفس النوع الأساسي مثل UserId و OrderId، واكتب التوقيعات العامة بأنواع مجردة مثل Sequence و Mapping بدل list و dict لتقبل مدخلات أوسع. تجنب generics المعقدة لكل متغير محلي؛ فتكلفة القراءة والصيانة يجب أن تكون أقل من الفائدة.
مثال بالكود
from collections.abc import Sequence
from typing import NewType
UserId = NewType("UserId", int)
OrderId = NewType("OrderId", int)
def cancel(order_id: OrderId, by: UserId) -> None: ...
def average(values: Sequence[float]) -> float:
return sum(values) / len(values)
cancel(UserId(7), OrderId(3)) # mypy يكتشف تبديل المعاملاتأخطاء شائعة
- استخدام list[int] في المعاملات العامة بدل Sequence[int] فترفض tuples بلا داعٍ.
- تمرير معرفات من أنواع مختلفة كـ int عادي فتختلط بدون أن يلاحظ أحد.