مفاهیم پیشرفتهتر تایپینگ در پایتون
پایتون از تایپینگ استاتیک پشتیبانی میکند که به برنامهنویسان کمک میکند کدهای خود را بهتر سازماندهی و از خطاهای تایپی جلوگیری کنند. در این بخش با چند مفهوم پیشرفتهتر تایپینگ آشنا میشویم:
Genericها
جنریکها اجازه میدهند کلاسها یا توابعی بسازیم که برای انواع مختلفی از دادهها قابل استفاده باشند بدون نیاز به تعریف جداگانه برای هر نوع. این باعث میشود کدها انعطافپذیر و قابلاستفاده مجدد باشند.
from typing import TypeVar, Generic, List
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self):
self.items: List[T] = []
def push(self, item: T) -> None:
self.items.append(item)
def pop(self) -> T:
return self.items.pop()
stack_int = Stack[int]()
stack_int.push(10)
stack_int.push(20)
print(stack_int.pop()) # خروجی: 20
پروتکلها (Protocols)
پروتکلها نوعی رابط هستند که مشخص میکنند یک کلاس باید چه متدها یا ویژگیهایی را داشته باشد. اگر یک کلاس این ویژگیها را داشته باشد، میتوان آن را به عنوان پیادهسازی آن پروتکل پذیرفت، حتی بدون ارثبری رسمی.
from typing import Protocol
class Drawable(Protocol):
def draw(self) -> None:
...
class Circle:
def draw(self) -> None:
print("Drawing a circle")
def paint(obj: Drawable) -> None:
obj.draw()
c = Circle()
paint(c) # خروجی: Drawing a circle
تایپینگ در پایتون به ما کمک میکند تا نوع دادههای ورودی و خروجی توابع را مشخص کنیم و به خوانایی، نگهداری و دیباگ کد کمک میکند. از نسخه 3.10 به بعد، سینتکس تایپینگ سادهتر و قابلفهمتر شده است. در این بخش با چند قابلیت تایپینگ پیشرفته آشنا میشویم.
Union Types (نوعهای اتحادی)
وقتی یک مقدار میتواند چند نوع مختلف داشته باشد، از Union استفاده میکنیم. در پایتون 3.10+ میتوان به جای Union[int, str]، از سینتکس سادهتر int | str استفاده کرد.
def process(value: int | str) -> None:
if isinstance(value, int):
print("Number:", value)
else:
print("Text:", value)
process(10)
process("hello")
TypeAlias (تعریف نام مستعار برای تایپ)
گاهی میخواهیم یک تایپ پیچیده را با نامی کوتاهتر و قابل فهمتر تعریف کنیم. برای این کار از TypeAlias استفاده میکنیم.
from typing import TypeAlias
UserId: TypeAlias = int | str
def get_user(user_id: UserId) -> None:
print("Fetching user with ID:", user_id)
get_user(123)
get_user("abc")
TypedDict (تایپ دیکشنریهای ساختارمند)
اگر دیکشنری ما ساختار مشخصی دارد و میخواهیم کلیدها و نوع مقادیر آن را تعیین کنیم، از TypedDict استفاده میکنیم.
from typing import TypedDict
class User(TypedDict):
id: int
name: str
is_active: bool
def print_user(user: User) -> None:
print(f"User {user['name']} (ID: {user['id']}) is", "active" if user["is_active"] else "inactive")
print_user({"id": 1, "name": "Ali", "is_active": True})
Callable (تایپ توابع به عنوان آرگومان)
وقتی میخواهیم یک تابع را به عنوان پارامتر به تابع دیگری بدهیم و نوع ورودی و خروجی آن تابع را مشخص کنیم، از Callable استفاده میکنیم.
from typing import Callable
def apply_func(x: int, func: Callable[[int], int]) -> int:
return func(x)
def square(n: int) -> int:
return n * n
result = apply_func(5, square)
print(result) # خروجی: 25
جمعبندی
تایپینگ پیشرفته در پایتون باعث میشود کد خواناتر و قابل اطمینانتر باشد و در زمان توسعه و دیباگ خطاها را سریعتر پیدا کنیم. استفاده از سینتکس جدید مانند int | str و list[int] کار با تایپها را راحتتر و طبیعیتر کرده است.