تعمل تلميحات نوع Python على تغيير طريقة كتابتك وقراءتك والحفاظ على كود Python. تمت إضافتها في Python 3.5 وتم تحسينها بشكل كبير من خلال 3.12+، وأصبحت تلميحات الكتابة الآن ممارسة قياسية في تطوير Python الاحترافي. يغطي هذا الدليل كل شيء بدءًا من الأساسيات وحتى الأنماط المتقدمة.
📋 Table of Contents
لماذا تعتبر تلميحات الكتابة مهمة في عام 2026؟
تظل لغة Python مكتوبة ديناميكيًا في وقت التشغيل، لكن تلميحات الكتابة توفر ما يلي:
- ذكاء بيئة تطوير متكاملة– الإكمال التلقائي، والانتقال إلى التعريف، وإعادة البناء في PyCharm وVS Code
- التحليل الساكن– يلتقط mypy وPyright الأخطاء قبل وقت التشغيل
- التوثيق– تشرح التوقيعات الوظيفية ما يدخل وما يخرج
- الثقة على نطاق واسع– إعادة هيكلة آمنة في قواعد التعليمات البرمجية الكبيرة
التعليقات التوضيحية الأساسية
from typing import Optional, Union
from datetime import datetime
# Variable annotations
name: str = "Alice"
age: int = 30
active: bool = True
scores: list[float] = [9.5, 8.7, 9.2]
config: dict[str, str] = {"env": "prod", "region": "us-east-1"}
# Function annotations
def greet(name: str, greeting: str = "Hello") -> str:
return f"{greeting}, {name}!"
def find_user(user_id: int) -> dict[str, str] | None:
# Python 3.10+ union syntax (| instead of Union[])
...
# None return type
def log(message: str) -> None:
print(f"[LOG] {message}")
المجموعات والأدوية العامة
from typing import Sequence, Mapping, Iterator, Generator
from collections.abc import Callable
# Built-in generics (Python 3.9+)
def first(items: list[int]) -> int | None:
return items[0] if items else None
def merge(a: dict[str, int], b: dict[str, int]) -> dict[str, int]:
return {**a, **b}
# Sequence — more general than list
def count_items(items: Sequence[str]) -> int:
return len(items)
# Callable type
def apply(func: Callable[[int, int], int], a: int, b: int) -> int:
return func(a, b)
result = apply(lambda x, y: x + y, 3, 4) # 7
# Generator type
def fibonacci() -> Generator[int, None, None]:
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# TypeVar for generic functions
from typing import TypeVar
T = TypeVar("T")
def identity(value: T) -> T:
return value
def first_item(items: list[T]) -> T | None:
return items[0] if items else None
TypedDict وفئات البيانات
from typing import TypedDict, Required, NotRequired
from dataclasses import dataclass, field
# TypedDict — typed dictionaries
class UserDict(TypedDict):
id: int
name: str
email: str
class PartialUser(TypedDict, total=False):
id: int
name: str
email: str
# With Required/NotRequired (Python 3.11+)
class Config(TypedDict):
host: Required[str]
port: Required[int]
debug: NotRequired[bool]
# Dataclass — cleaner than TypedDict for classes
@dataclass
class Product:
id: int
name: str
price: float
tags: list[str] = field(default_factory=list)
active: bool = True
def apply_discount(self, percent: float) -> "Product":
return Product(
id=self.id,
name=self.name,
price=self.price * (1 - percent / 100),
tags=self.tags,
active=self.active
)
# frozen=True for immutability
@dataclass(frozen=True)
class Point:
x: float
y: float
البروتوكول – التصنيف الفرعي الهيكلي
تحدد البروتوكولات واجهات بدون وراثة:
from typing import Protocol, runtime_checkable
@runtime_checkable
class Drawable(Protocol):
def draw(self) -> None: ...
def get_area(self) -> float: ...
class Circle:
def __init__(self, radius: float):
self.radius = radius
def draw(self) -> None:
print(f"Drawing circle r={self.radius}")
def get_area(self) -> float:
import math
return math.pi * self.radius ** 2
class Rectangle:
def __init__(self, width: float, height: float):
self.width = width
self.height = height
def draw(self) -> None:
print(f"Drawing rect {self.width}x{self.height}")
def get_area(self) -> float:
return self.width * self.height
def render_all(shapes: list[Drawable]) -> None:
for shape in shapes:
shape.draw()
print(f"Area: {shape.get_area():.2f}")
# Works without inheritance — structural compatibility
shapes: list[Drawable] = [Circle(5.0), Rectangle(3.0, 4.0)]
render_all(shapes)
الأنواع الحرفية والنهائية
from typing import Literal, Final, TypeAlias
# Literal — restrict to specific values
def set_direction(direction: Literal["north", "south", "east", "west"]) -> None:
print(f"Moving {direction}")
set_direction("north") # OK
set_direction("up") # mypy error!
# Final — constants that cannot be reassigned
MAX_RETRIES: Final = 3
BASE_URL: Final[str] = "https://api.example.com"
# TypeAlias — named type aliases (Python 3.10+)
Vector: TypeAlias = list[float]
Matrix: TypeAlias = list[Vector]
JSON: TypeAlias = dict[str, "JSONValue"]
JSONValue: TypeAlias = str | int | float | bool | None | list["JSONValue"] | JSON
ParamSpec وTypeVarTuple (متقدم)
from typing import ParamSpec, TypeVar, Callable
import functools
import time
P = ParamSpec("P")
R = TypeVar("R")
# Type-safe decorator that preserves signature
def retry(max_attempts: int = 3):
def decorator(func: Callable[P, R]) -> Callable[P, R]:
@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts - 1:
raise
time.sleep(2 ** attempt)
raise RuntimeError("unreachable")
return wrapper
return decorator
@retry(max_attempts=3)
def fetch_data(url: str, timeout: int = 30) -> dict:
import requests
return requests.get(url, timeout=timeout).json()
تكوين mypy وPyright
# pyproject.toml
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_ignores = true
no_implicit_reexport = true
# Pyright (pyrightconfig.json or pyproject.toml)
[tool.pyright]
pythonVersion = "3.12"
typeCheckingMode = "strict"
reportMissingTypeStubs = false
اكتب أنماط التضييق
from typing import assert_never
type Shape = Circle | Rectangle | Triangle # Python 3.12 type statement
def get_area(shape: Shape) -> float:
match shape:
case Circle(radius=r):
return 3.14159 * r * r
case Rectangle(width=w, height=h):
return w * h
case Triangle(base=b, height=h):
return 0.5 * b * h
case _ as unreachable:
assert_never(unreachable) # exhaustiveness check
ملخص
تعتبر تلميحات نوع بايثون في عام 2026 ضرورية للتطوير المهني. استخدمها في كل التعليمات البرمجية الجديدة، وقم بتمكين التحقق الصارم من mypy/Pyright، واستفد من البروتوكول لكتابة البطة. يكون تأثير أداء وقت التشغيل صفرًا — حيث يتم مسح الأنواع في وقت التنفيذ.
🔗 Share this article
✍️ Leave a Comment