Type Hints در پایتون چیست؟

آموزش Type Annotation در پایتون به زبان ساده همراه با مثال‌های کاربردی

Type Hint چیست؟

پایتون یک زبان با Dynamic Typing است؛ یعنی هنگام تعریف متغیر معمولاً لازم نیست نوع داده را به‌صورت جداگانه مشخص کنیم.

name = "PythonAI"
age = 25
price = 19.99

با این حال در پروژه‌های بزرگ‌تر، مشخص بودن نوع مورد انتظار متغیرها و پارامترهای تابع می‌تواند خوانایی و نگهداری کد را ساده‌تر کند.

در پایتون می‌توانیم با استفاده از Type Hint یا Type Annotation نوع مورد انتظار داده را مشخص کنیم.

Type Hint برای متغیرها

برای مشخص کردن نوع یک متغیر، بعد از نام متغیر علامت : قرار می‌دهیم.

name: str = "Ali"

age: int = 25

price: float = 19.99

is_active: bool = True

در این مثال به ترتیب مشخص کرده‌ایم که نوع مورد انتظار name رشته، age عدد صحیح، price عدد اعشاری و is_active مقدار منطقی است.

Type Hint برای انواع داده پایه

برای انواع داده رایج می‌توان از Type Hintهای زیر استفاده کرد:

name: str = "Sara"

age: int = 30

height: float = 1.72

student: bool = True
  • str برای رشته‌ها
  • int برای اعداد صحیح
  • float برای اعداد اعشاری
  • bool برای True و False

Type Hint برای تابع‌ها

یکی از مهم‌ترین کاربردهای Type Hint مشخص کردن نوع پارامترهای تابع و مقدار بازگشتی آن است.

def greet(name: str) -> str:

    return "Hello " + name

در این مثال مشخص کرده‌ایم که پارامتر name از نوع str است و تابع یک مقدار از نوع str برمی‌گرداند.

Type Hint برای چند پارامتر

def add(a: int, b: int) -> int:

    return a + b

این تابع دو عدد صحیح دریافت می‌کند و یک عدد صحیح برمی‌گرداند.

مثال:

result = add(10, 20)

print(result)

خروجی:

30

تابعی که مقدار بازگشتی ندارد

اگر تابع قرار نیست مقدار مشخصی برگرداند، می‌توان از None استفاده کرد.

def show_message(message: str) -> None:

    print(message)

این Type Hint نشان می‌دهد که تابع مقدار قابل استفاده‌ای با return برنمی‌گرداند.

Type Hint برای List

برای مشخص کردن نوع عناصر یک لیست می‌توان از list استفاده کرد.

numbers: list[int] = [10, 20, 30, 40]

یعنی انتظار داریم عناصر این لیست از نوع int باشند.

برای رشته‌ها:

names: list[str] = [
    "Ali",
    "Sara",
    "Reza"
]

این نوع نوشتار در نسخه‌های جدید پایتون بسیار رایج است.

Type Hint برای Dictionary

برای دیکشنری می‌توان نوع کلید و مقدار را مشخص کرد.

users: dict[str, int] = {
    "Ali": 20,
    "Sara": 25,
    "Reza": 30
}

در این مثال کلیدها از نوع str و مقادیر از نوع int هستند.

Type Hint برای Tuple

برای Tuple نیز می‌توان نوع عناصر را مشخص کرد.

person: tuple[str, int] = ("Ali", 25)

در این مثال عنصر اول رشته و عنصر دوم عدد صحیح است.

Type Hint برای Set

برای Set می‌توان نوع عناصر را مشخص کرد.

numbers: set[int] = {
    1, 2, 3, 4, 5
}

Optional در Type Hint چیست؟

گاهی یک متغیر می‌تواند یک نوع مشخص داشته باشد یا مقدار None باشد.

برای چنین حالتی می‌توان از Optional استفاده کرد.

from typing import Optional


username: Optional[str] = None

یعنی username می‌تواند یک رشته یا مقدار None باشد.

در نسخه‌های جدید پایتون می‌توان این مفهوم را با علامت | نیز نوشت:

username: str | None = None

Union در پایتون

گاهی یک متغیر یا پارامتر می‌تواند یکی از چند نوع مختلف باشد.

در نسخه‌های قدیمی‌تر می‌توان از Union استفاده کرد:

from typing import Union


def show_id(user_id: Union[int, str]) -> None:

    print(user_id)

در نسخه‌های جدید پایتون می‌توان همین مفهوم را ساده‌تر نوشت:

def show_id(user_id: int | str) -> None:

    print(user_id)

Any در Type Hint چیست؟

نوع Any زمانی استفاده می‌شود که نوع داده مشخص یا محدود نشده باشد.

from typing import Any


value: Any = 10

value = "Python"

value = [1, 2, 3]

با Any تقریباً هر نوع مقداری قابل قبول است.

البته بهتر است زمانی از Any استفاده کنیم که واقعاً به آن نیاز داریم و در صورت امکان نوع دقیق‌تری برای داده مشخص کنیم.

Type Alias چیست؟

اگر یک Type Hint طولانی یا پیچیده داشته باشیم، می‌توانیم برای آن یک نام ایجاد کنیم.

type UserData = dict[str, int]

سپس می‌توانیم از آن نام در قسمت‌های مختلف برنامه استفاده کنیم:

users: UserData = {
    "Ali": 20,
    "Sara": 25
}

این کار می‌تواند خوانایی کد را در پروژه‌های بزرگ افزایش دهد.

یک مثال کاربردی با Type Hint

فرض کنیم تابعی داریم که اطلاعات یک کاربر را دریافت می‌کند.

def create_user(
    name: str,
    age: int,
    active: bool
) -> dict:

    return {
        "name": name,
        "age": age,
        "active": active
    }

حالا مشخص است که تابع چه نوع داده‌هایی دریافت می‌کند و یک Dictionary برمی‌گرداند.

Type Hint برای کلاس‌ها

Type Hint فقط برای متغیرها و تابع‌ها نیست و در کلاس‌ها نیز می‌توان از آن استفاده کرد.

class User:

    name: str
    age: int

    def __init__(self, name: str, age: int):

        self.name = name
        self.age = age

این روش باعث می‌شود ساختار داده‌های کلاس واضح‌تر شود.

آیا Type Hint نوع داده را تغییر می‌دهد؟

خیر.

Type Hint به‌تنهایی نوع داده را در زمان اجرای برنامه تغییر نمی‌دهد و پایتون صرفاً به خاطر نوشتن Type Hint مقدار را به آن نوع تبدیل نمی‌کند.

age: int = "Ali"

این کد از نظر Type Hint نادرست است، اما Type Hint به‌تنهایی مانند یک تبدیل‌کننده نوع در زمان اجرا عمل نمی‌کند.

ابزارهای تحلیل کد و Type Checkerها می‌توانند چنین ناسازگاری‌هایی را به توسعه‌دهنده هشدار دهند.

Type Checker چیست؟

Type Checker ابزاری است که Type Hintهای کد را بررسی می‌کند و می‌تواند ناسازگاری‌های احتمالی را قبل از اجرای برنامه به ما نشان دهد.

یکی از ابزارهای شناخته‌شده در این زمینه mypy است.

همچنین ویرایشگرهایی مانند VS Code می‌توانند با استفاده از ابزارهای تحلیل کد، بعضی از مشکلات مربوط به Type Hint را به توسعه‌دهنده نشان دهند.

مزایای Type Hint

  • افزایش خوانایی کد
  • مشخص شدن نوع مورد انتظار داده‌ها
  • کمک به پیدا کردن خطاهای احتمالی
  • بهتر شدن تجربه کار با IDE
  • مناسب برای پروژه‌های بزرگ
  • ساده‌تر شدن نگهداری و توسعه کد
  • کمک به همکاری چند برنامه‌نویس روی یک پروژه

اشتباهات رایج در Type Hint

۱. تصور اینکه Type Hint تبدیل نوع انجام می‌دهد

Type Hint به‌تنهایی مقدار را تبدیل نمی‌کند.

۲. استفاده بیش از حد از Any

اگر نوع داده مشخص است، بهتر است به جای Any نوع دقیق آن را بنویسیم.

۳. نوشتن Type Hint نادرست

Type Hint باید با رفتار واقعی برنامه هماهنگ باشد. اگر تابع چند نوع داده را قبول می‌کند، باید این موضوع در Type Hint نیز مشخص شود.

مثال کامل Type Hint در یک برنامه کوچک

def calculate_total(
    price: float,
    quantity: int
) -> float:

    return price * quantity


price: float = 25.5

quantity: int = 3

total: float = calculate_total(
    price,
    quantity
)

print(total)

در این مثال نوع پارامترهای تابع، نوع خروجی تابع و نوع متغیرهای اصلی برنامه مشخص شده است.

جمع‌بندی Type Hints در پایتون

Type Hint یکی از قابلیت‌های مهم پایتون برای مشخص کردن نوع مورد انتظار داده‌هاست.

می‌توان از Type Hint برای متغیرها، پارامترهای تابع، مقدار بازگشتی، لیست‌ها، دیکشنری‌ها، کلاس‌ها و ساختارهای پیچیده‌تر استفاده کرد.

ابزارهایی مانند Optional، Union و Any نیز برای تعریف حالت‌های مختلف داده کاربرد دارند.

در پروژه‌های بزرگ، Type Hint می‌تواند خوانایی، نگهداری و تحلیل کد را آسان‌تر کند.

تمرین‌های Type Hints

  1. متغیری به نام name تعریف کنید که Type Hint آن str باشد.
  2. تابعی به نام multiply بنویسید که دو عدد int دریافت کند و حاصل ضرب آن‌ها را برگرداند.
  3. یک لیست از اعداد صحیح با Type Hint مناسب ایجاد کنید.
  4. تابعی بنویسید که یک نام را دریافت کند و str | None برگرداند.
  5. یک Dictionary ایجاد کنید که کلیدهای آن str و مقادیر آن float باشند.
  6. یک کلاس ساده ایجاد کنید و برای ویژگی‌های آن Type Hint بنویسید.

سوالات متداول درباره Type Hints

Type Hint در پایتون چیست؟

Type Hint روشی برای مشخص کردن نوع مورد انتظار متغیرها، پارامترهای تابع و مقدار بازگشتی تابع است.

آیا Type Hint اجباری است؟

خیر. پایتون برای اجرای معمول برنامه‌ها شما را مجبور به نوشتن Type Hint نمی‌کند.

آیا Type Hint سرعت برنامه را افزایش می‌دهد؟

هدف اصلی Type Hint افزایش خوانایی و کمک به ابزارهای تحلیل کد است و به‌طور معمول به‌تنهایی باعث افزایش مستقیم سرعت اجرای برنامه نمی‌شود.

Optional در پایتون چه کاربردی دارد؟

برای مشخص کردن مقداری استفاده می‌شود که می‌تواند یک نوع مشخص یا None باشد.

تفاوت Type Hint و Type Checking چیست؟

Type Hint اطلاعاتی درباره نوع مورد انتظار داده ارائه می‌دهد، در حالی که Type Checking فرآیند بررسی سازگاری کد با این نوع‌هاست.

آیا Type Hint فقط برای پروژه‌های بزرگ است؟

خیر. حتی در پروژه‌های کوچک نیز می‌تواند خوانایی کد را بهتر کند، اما در پروژه‌های بزرگ اهمیت بیشتری پیدا می‌کند.