زبانها معمولاً یا تعیین نوع پویا دارند؛ مانند کامن لیسپ، پایتون، جاوا اسکریپت یا دارای تعیین نوع ایستا هستند؛ مانند سی و سیپلاسپلاس، راست و دوباره کامن لیسپ (معمولاً پیادهسازیهای مدرن کامن لیسپ، مانند SBCL، اجازه میدهند بنا به خواست برنامهنویس، قسمتی از کد، دارای تعیین نوع ایستا و قسمتی دارای تعیین نوع پویا باشد).
در پایتون، تعیین نوع متغیرها، مقدار یا مقادیر بازگشتی توابع و متدها و آرگومانهای توابع اجباری نیست. اما میتوانیم با تعیین نوع و استفاده از یک نرمافزار Linter به کاهش خطاهای خود پیش از اجرا کمک کنیم.
def f(x: int) - > int:
return x * 2 + 1
با این که تعیین نوع آرگومان یا ورودی تابع f که x باشد و مقدار بازگشت آن یعنی x*2 + 1
در اجرا تأثیری ندارد، اما زمانی که بخواهم مقدار بازگشت تابع f را با یک رشته نویسه (کاراکتر) جمع کنم به من اخطار داده میشود:
بدیهی است که اجرای این برنامه به وسیلهٔ پایتون نیز باعث خطا میشود. در مقابل زمانی که نوع ورودی و خروجی تابع را مشخص نمیکنم اخطاری داده نمیشود:
در ادامه با تعیین نوع ورودیها و خروجی توابع و متدها و ویژگیهای یک کلاس آشنا میشویم.
تعیین نوع متغیرها
تغییر نوع یک متغیر زمان ایجاد، قالب زیر را دارد:
<variable_name>: <type> = <value>
برای مثال:
i: int = 10
s: str = “Hello”
اما در مورد مخازن پایتون زمانی که بخواهیم عناصر مخزن همه از یک نوع باشند دیگر تغییر نوع به این صورت کافی نیست. البته میتوانیم متغیر my_list
را به صورت لیست تعیین کنیم اما این تعیین به آنالیزگر و یا یک خوانندهٔ دیگر کد نمیگوید در لیست چه چیزهایی ذخیره میشوند.
برای تعیین نوع عناصر یک لیست یا فهرست باید از ماژول typing پایتون کمک بگیریم و به عنوان مثال مشخص کنیم که تمام عناصر یک لیست عدد صحیح هستند:
from typing import List
my_list: List[int] = [1,2,3]
حال زمانی که بخواهیم به لیست my_list
یک رشته کاراکتر اضافه کنیم، نرمافزار لینتر خطا میدهد:
به همین صورت نیز میتوانیم برای یک توپل مشخص کنیم چه نوع عناصری در آن وجود دارند و البته چه تعداد:
from typing import Tuple
t: Tuple[int, int, int] = (1, 2, 3)
d: Tuple[int, …] = (1, 2, 3, 4, 5, 6, 7)
و نهایتاً برای یک دیکشنری میتوانیم نوع کلید و همچنین مقدار را مشخص کنیم:
from typing import Dict
d: Dict[int, int] = {1: 10, 2: 13}
در تکه کد بالا d یک دیکشنری با کلیدهایی از نوع عدد صحیح و همینطور مقادیری از همین نوع میباشد.
توجه کنید از پایتون ۳٫۹ به بعد استفاده از ماژول typing
برای تعیین نوع دیکشنریها، لیستها و توپلها منسوخ شده و میتوانید از خود نوع دادهها استفاده کنید:
d: dict[int, int] = {1: 10}
my_list: list[int] = [1, 2, 3]
mt: tuple[int, int] = (1, 2)
نوع Callable نیز در پایتون برای هر «قابل صدازدنی» مانند توابع یا کلاسهایی که __call__
را پیادهسازی میکنند وجود دارد. در مثال زیر ورودی تابع exec
میتواند هر تابعی باشد که دارای تکورودی int
و خروجی float
است:
from typing import Callable
def exec(cb: Callable[[int], float]) → None:
…
تعیین نوع ورودی و خروجی توابع و متدها
تابع func
در مثال زیر دو ورودی x
و y
هر دو از نوع عدد صحیح دریافت میکند و خروجی آن یک عدد صحیح است:
def func(x: int, y: int) → int:
return 2**y + 2**y – 1
برای متدها نیز به همین شکل عمل میکنیم.
کلاسهای داده
در پایتون با استفاده از دیکوریتور(decorator) dataclass
میتوانید کلاسهای داده ایجاد کنید و نوع ویژگیها را مشخص کنید:
from dataclasses import dataclass
@dataclass
class Human:
age: int
name: str
children: list[str]
توجه کنید که این دیکوریتور خود نوع دادهها را زمان ایجاد نمونه از کلاس بررسی نمیکند.