typing --- پشتیبانی از راهنماهای نوع¶
اضافه شده در نسخهی 3.5.
کد منبع: Lib/typing.py
توجه
رانتایم پایتون حاشیهنویسیهای نوع توابع و متغیرها را اعمال نمیکند. این حاشیهنویسیها میتوانند توسط ابزارهای شخص ثالث مانند بررسیکنندههای نوع، IDEها، لینترها و غیره مورد استفاده قرار گیرند.
این ماژول پشتیبانی در رانتایم برای راهنماهای نوع را فراهم میکند.
تابع زیر را در نظر بگیرید:
def surface_area_of_cube(edge_length: float) -> str:
return f"The surface area of the cube is {6 * edge_length ** 2}."
تابع surface_area_of_cube یک آرگومان میگیرد که انتظار میرود نمونهای از float باشد، همانطور که type hint edge_length: float نشان میدهد. انتظار میرود تابع نمونهای از str را برگرداند، همانطور که اشاره -> str نشان میدهد.
اگرچه راهنماهای نوع میتوانند کلاسهای سادهای مانند float یا str باشند، اما میتوانند پیچیدهتر نیز باشند. ماژول typing واژگانی از راهنماهای نوع پیشرفتهتر را فراهم میکند.
قابلیتهای جدید اغلب به ماژول typing اضافه میشوند. بسته typing_extensions بکپورتهایی (backports) از این قابلیتهای جدید را به نسخههای قدیمیتر پایتون ارائه میدهد.
همچنین ملاحظه نمائید
- برگه تقلب نوعدهی (Typing)
مروری سریع بر راهنماهای نوع (میزبانیشده در مستندات mypy)
- بخش Type System Reference از مستندات mypy
سیستم نوعدهی پایتون از طریق PEPها استاندارد شده است، بنابراین این مرجع باید بهطور گسترده برای بیشتر بررسیکنندههای نوع پایتون صدق کند. (برخی بخشها ممکن است همچنان مختص mypy باشند.)
- نوعدهی ایستا با پایتون
مستندات مستقل از بررسیکننده نوع که توسط کامیونیتی نوشته شده است و ویژگیهای سیستم نوع، ابزارهای مفید مرتبط با نوعدهی و بهترین شیوههای نوعدهی را با جزئیات شرح میدهد.
مشخصات سیستم نوع پایتون¶
مشخصات کانونیکال و بهروز سیستم نوع پایتون را میتوانید در مشخصات سیستم نوع پایتون پیدا کنید.
نامهای مستعار نوع¶
یک ناممستعار نوع با استفاده از دستور type تعریف میشود، که یک نمونه از TypeAliasType را ایجاد میکند. در این مثال، از نظر بررسیکنندههای نوع ایستا، Vector و list[float] معادل یکدیگر در نظر گرفته میشوند:
type Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# passes type checking; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
نامهای مستعار نوع برای سادهسازی امضاهای نوع پیچیده مفید هستند. برای مثال:
from collections.abc import Sequence
type ConnectionOptions = dict[str, str]
type Address = tuple[str, int]
type Server = tuple[Address, ConnectionOptions]
def broadcast_message(message: str, servers: Sequence[Server]) -> None:
...
# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
message: str,
servers: Sequence[tuple[tuple[str, int], dict[str, str]]]
) -> None:
...
دستور type در پایتون 3.12 جدید است. برای سازگاری با نسخههای پیشین، میتوان نامهای مستعار نوع را نیز از طریق انتساب ساده ایجاد کرد:
Vector = list[float]
یا با TypeAlias علامتگذاری شود تا بهصراحت مشخص شود که این یک نام مستعار نوع است، نه یک انتساب متغیر معمولی:
from typing import TypeAlias
Vector: TypeAlias = list[float]
NewType¶
برای ایجاد انواع متمایز، از کمکی NewType استفاده کنید:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
بررسیگر نوع ایستا با نوع جدید بهگونهای رفتار میکند که گویی زیرکلاسی از نوع اصلی است. این برای کمک به شناسایی خطاهای منطقی مفید است:
def get_user_name(user_id: UserId) -> str:
...
# passes type checking
user_a = get_user_name(UserId(42351))
# fails type checking; an int is not a UserId
user_b = get_user_name(-1)
شما همچنان میتوانید تمام عملیاتهای int را روی متغیری از نوع UserId انجام دهید، اما نتیجه همیشه از نوع int خواهد بود. این امکان را به شما میدهد که هر جا که ممکن است یک int مورد انتظار باشد، یک UserId را ارسال کنید، اما از ایجاد اشتباهی یک UserId بهصورت نامعتبر جلوگیری میکند:
# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)
توجه داشته باشید که این بررسیها فقط توسط بررسیکننده نوع ایستا اعمال میشوند. در رانتایم، دستور Derived = NewType('Derived', Base)، Derived را به یک شیء فراخوانیپذیر تبدیل میکند که بلافاصله هر پارامتری را که به آن بدهید برمیگرداند. این بدان معناست که عبارت Derived(some_value) کلاس جدیدی ایجاد نمیکند و سربار زیادی فراتر از یک فراخوانی تابع معمولی به همراه ندارد.
بهطور دقیقتر، عبارت some_value is Derived(some_value) همیشه در رانتایم درست است.
ایجاد یک زیرنوع از Derived نامعتبر است:
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not pass type checking
class AdminUserId(UserId): pass
با این حال، امکان ایجاد یک NewType بر پایهی یک NewType «مشتقشده» وجود دارد:
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
و بررسی نوع برای ProUserId مطابق انتظار کار خواهد کرد.
برای جزئیات بیشتر PEP 484 را ببینید.
توجه
به یاد داشته باشید که استفاده از یک نام مستعار نوع، دو نوع را معادل یکدیگر اعلام میکند. انجام type Alias = Original باعث میشود بررسیکننده نوع ایستا، Alias را در همه موارد دقیقاً معادل Original در نظر بگیرد. این زمانی مفید است که بخواهید امضاهای نوع پیچیده را سادهتر کنید.
در مقابل، NewType یک نوع را زیرنوع نوع دیگری اعلام میکند. انجام Derived = NewType('Derived', Original) باعث میشود بررسیگر نوع ایستا با Derived بهعنوان زیرکلاس Original رفتار کند، که به این معناست که نمیتوان از مقداری از نوع Original در مواردی استفاده کرد که مقداری از نوع Derived مورد انتظار است. این موضوع زمانی مفید است که بخواهید از خطاهای منطقی با کمترین هزینهی رانتایم جلوگیری کنید.
اضافه شده در نسخهی 3.5.2.
تغییر یافته در نسخهی 3.10: NewType اکنون یک کلاس است، نه یک تابع. در نتیجه، هنگام فراخوانی NewType نسبت به یک تابع معمولی، مقداری هزینهی رانتایم اضافی وجود دارد.
تغییر یافته در نسخهی 3.11: عملکرد فراخوانی NewType به سطح آن در Python 3.9 بازگردانده شده است.
حاشیهنویسی اشیاء فراخوانیپذیر¶
توابع — یا دیگر اشیاء callable — میتوانند با collections.abc.Callable یا typing.Callable منسوخ حاشیهنویسی شوند. Callable[[int], str] نشاندهنده تابعی است که تنها یک پارامتر از نوع int میگیرد و یک str برمیگرداند.
برای مثال:
from collections.abc import Callable, Awaitable
def feeder(get_next_item: Callable[[], str]) -> None:
... # Body
def async_query(on_success: Callable[[int], None],
on_error: Callable[[int, Exception], None]) -> None:
... # Body
async def on_update(value: str) -> None:
... # Body
callback: Callable[[str], Awaitable[None]] = on_update
نحوِ زیرنویسی (subscription) باید همواره دقیقاً با دو مقدار استفاده شود: فهرست آرگومانها و نوع بازگشتی. فهرست آرگومانها باید فهرستی از انواع، یک ParamSpec، Concatenate، یا یک سهنقطه (...) باشد. نوع بازگشتی باید یک نوع واحد باشد.
اگر یک سهنقطه (ellipsis) بهصورت ... بهعنوان فهرست آرگومانها داده شود، نشان میدهد که یک فراخوانیپذیر با هر فهرست پارامتر دلخواهی قابلقبول است:
def concat(x: str, y: str) -> str:
return x + y
x: Callable[..., str]
x = str # OK
x = concat # Also OK
Callable نمیتواند امضاهای پیچیده را بیان کند، مانند توابعی که تعداد متغیری از آرگومانها را میپذیرند، توابع سربارگذاریشده (overloaded)، یا توابعی که پارامترهای فقط کلیدواژهای دارند. با این حال، این امضاها را میتوان با تعریف یک کلاس Protocol با متد __call__() بیان کرد:
from collections.abc import Iterable
from typing import Protocol
class Combiner(Protocol):
def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ...
def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes:
for item in data:
...
def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]:
...
def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]:
...
batch_proc([], good_cb) # OK
batch_proc([], bad_cb) # Error! Argument 2 has incompatible type because of
# different name and kind in the callback
فراخوانیپذیرهایی که فراخوانیپذیرهای دیگر را بهعنوان آرگومان میپذیرند، میتوانند با استفاده از ParamSpec نشان دهند که نوع پارامترهایشان به یکدیگر وابسته است. علاوه بر این، اگر آن فراخوانیپذیر آرگومانهایی را به فراخوانیپذیرهای دیگر اضافه کند یا از آنها حذف کند، میتوان از عملگر Concatenate استفاده کرد. آنها بهترتیب به شکل Callable[ParamSpecVariable, ReturnType] و Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType] هستند.
تغییر یافته در نسخهی 3.10: اکنون Callable از ParamSpec و Concatenate پشتیبانی میکند. برای جزئیات بیشتر PEP 612 را ببینید.
همچنین ملاحظه نمائید
مستندات مربوط به ParamSpec و Concatenate نمونههایی از کاربرد در Callable ارائه میدهد.
عامها¶
از آنجا که اطلاعات نوعِ شیءهای نگهداریشده در ظرفها را نمیتوان بهصورت ایستا و به شکلی عام استنتاج کرد، بسیاری از کلاسهای ظرف در کتابخانهی استاندارد از زیرنویسی پشتیبانی میکنند تا انواع مورد انتظار عناصر ظرف را مشخص کنند.
from collections.abc import Mapping, Sequence
class Employee: ...
# Sequence[Employee] indicates that all elements in the sequence
# must be instances of "Employee".
# Mapping[str, str] indicates that all keys and all values in the mapping
# must be strings.
def notify_by_email(employees: Sequence[Employee],
overrides: Mapping[str, str]) -> None: ...
توابع عام و کلاسها را میتوان با استفاده از سینتکس پارامتر نوع پارامتریزه کرد:
from collections.abc import Sequence
def first[T](l: Sequence[T]) -> T: # Function is generic over the TypeVar "T"
return l[0]
یا با استفادهی مستقیم از کارخانهی TypeVar:
from collections.abc import Sequence
from typing import TypeVar
U = TypeVar('U') # Declare type variable "U"
def second(l: Sequence[U]) -> U: # Function is generic over the TypeVar "U"
return l[1]
تغییر یافته در نسخهی 3.12: پشتیبانی سینتکسی از ژنریکها (generics) در پایتون 3.12 جدید است.
حاشیهنویسی تاپلها¶
برای بیشتر ظرفها در پایتون، سیستم نوعدهی فرض میکند که تمام عناصر داخل ظرف از یک نوع باشند. برای مثال:
from collections.abc import Mapping
# Type checker will infer that all elements in ``x`` are meant to be ints
x: list[int] = []
# Type checker error: ``list`` only accepts a single type argument:
y: list[int, str] = [1, 'foo']
# Type checker will infer that all keys in ``z`` are meant to be strings,
# and that all values in ``z`` are meant to be either strings or ints
z: Mapping[str, str | int] = {}
list تنها یک آرگومان نوعی را میپذیرد، بنابراین یک بررسیگر نوع برای انتساب y در بالا خطایی را نشان میدهد. به همین ترتیب، Mapping تنها دو آرگومان نوعی را میپذیرد: اولی نوع کلیدها و دومی نوع مقادیر را نشان میدهد.
با این حال، برخلاف بیشتر ظرفهای دیگر پایتون، در کد پایتون مصطلح رایج است که تاپلها عناصری داشته باشند که همهی آنها از یک نوع نیستند. به همین دلیل، تاپلها در سامانهی نوعدهی پایتون حالت خاصی دارند. tuple هر تعداد آرگومان نوع را میپذیرد:
# OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int
x: tuple[int] = (5,)
# OK: ``y`` is assigned to a tuple of length 2;
# element 1 is an int, element 2 is a str
y: tuple[int, str] = (5, "foo")
# Error: the type annotation indicates a tuple of length 1,
# but ``z`` has been assigned to a tuple of length 3
z: tuple[int] = (1, 2, 3)
برای نشان دادن یک تاپل که میتواند هر طولی داشته باشد و همهی عناصر آن از نوع یکسان T باشند، از سهنقطهی لفظی (ellipsis) ... استفاده کنید: tuple[T, ...]. برای نشان دادن یک تاپل خالی، از tuple[()] استفاده کنید. استفاده از tuple ساده بهعنوان حاشیهنویسی معادل استفاده از tuple[Any, ...] است:
x: tuple[int, ...] = (1, 2)
# These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length
x = (1, 2, 3)
x = ()
# This reassignment is an error: all elements in ``x`` must be ints
x = ("foo", "bar")
# ``y`` can only ever be assigned to an empty tuple
y: tuple[()] = ()
z: tuple = ("foo", "bar")
# These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]``
z = (1, 2, 3)
z = ()
نوع اشیای کلاس¶
متغیری که با C حاشیهنویسیشده است میتواند مقداری از نوع C را بپذیرد. در مقابل، متغیری که با type[C] (یا typing.Type[C] منسوخ) حاشیهنویسیشده است میتواند مقادیری را بپذیرد که خودشان کلاس هستند — بهطور مشخص، شیء کلاس C را خواهد پذیرفت. برای مثال:
a = 3 # Has type ``int``
b = int # Has type ``type[int]``
c = type(a) # Also has type ``type[int]``
توجه داشته باشید که type[C] هموردا (covariant) است:
class User: ...
class ProUser(User): ...
class TeamUser(User): ...
def make_new_user(user_class: type[User]) -> User:
# ...
return user_class()
make_new_user(User) # OK
make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]``
make_new_user(TeamUser) # Still fine
make_new_user(User()) # Error: expected ``type[User]`` but got ``User``
make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]``
تنها پارامترهای مجاز برای type عبارتاند از کلاسها، Any، type variables و اجتماعهایی از هر یک از این انواع. برای مثال:
def new_non_team_user(user_class: type[BasicUser | ProUser]): ...
new_non_team_user(BasicUser) # OK
new_non_team_user(ProUser) # OK
new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype
# of ``type[BasicUser | ProUser]``
new_non_team_user(User) # Also an error
type[Any] معادل type است که ریشهی سلسلهمراتب فراکلاسها در پایتون است.
حاشیهنویسی تولیدگرها و همروالها¶
یک تولیدگر میتواند با استفاده از نوع عام Generator[YieldType, SendType, ReturnType] حاشیهنویسی شود. برای مثال:
def echo_round() -> Generator[int, float, str]:
sent = yield 0
while sent >= 0:
sent = yield round(sent)
return 'Done'
توجه داشته باشید که برخلاف بسیاری دیگر از کلاسهای عام در کتابخانه استاندارد، SendTypeِ Generator رفتار پادوردا (contravariantly) دارد، نه هموردا (covariantly) یا ناوردا (invariantly).
مقدار پیشفرض پارامترهای SendType و ReturnType برابر با None است:
def infinite_stream(start: int) -> Generator[int]:
while True:
yield start
start += 1
همچنین امکان تنظیم این نوعها بهصورت صریح وجود دارد:
def infinite_stream(start: int) -> Generator[int, None, None]:
while True:
yield start
start += 1
تولیدگرهای سادهای که تنها مقادیر را yield میکنند، همچنین میتوانند بهعنوان داشتن نوع بازگشت Iterable[YieldType] یا Iterator[YieldType] حاشیهنویسی شوند:
def infinite_stream(start: int) -> Iterator[int]:
while True:
yield start
start += 1
تولیدگرهای ناهمگام به شیوهای مشابه مدیریت میشوند، اما انتظار آرگومان نوع ReturnType را نداشته باشید (AsyncGenerator[YieldType, SendType]). آرگومان SendType بهطور پیشفرض None است، بنابراین تعاریف زیر معادل هستند:
async def infinite_stream(start: int) -> AsyncGenerator[int]:
while True:
yield start
start = await increment(start)
async def infinite_stream(start: int) -> AsyncGenerator[int, None]:
while True:
yield start
start = await increment(start)
مانند حالت همگام، AsyncIterable[YieldType] و AsyncIterator[YieldType] نیز در دسترس هستند:
async def infinite_stream(start: int) -> AsyncIterator[int]:
while True:
yield start
start = await increment(start)
همروالها را میتوان با استفاده از Coroutine[YieldType, SendType, ReturnType] حاشیهنویسی کرد. آرگومانهای عام متناظر با آرگومانهای Generator هستند، برای مثال:
from collections.abc import Coroutine
c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere
x = c.send('hi') # Inferred type of 'x' is list[str]
async def bar() -> None:
y = await c # Inferred type of 'y' is int
انواع عام تعریفشده توسط کاربر¶
یک کلاس تعریفشده توسط کاربر میتواند بهعنوان یک کلاس عام تعریف شود.
from logging import Logger
class LoggedVar[T]:
def __init__(self, value: T, name: str, logger: Logger) -> None:
self.name = name
self.logger = logger
self.value = value
def set(self, new: T) -> None:
self.log('Set ' + repr(self.value))
self.value = new
def get(self) -> T:
self.log('Get ' + repr(self.value))
return self.value
def log(self, message: str) -> None:
self.logger.info('%s: %s', self.name, message)
این سینتکس نشان میدهد که کلاس LoggedVar با یک متغیر نوع واحد T پارامتریزهشده است. این موضوع همچنین T را بهعنوان یک نوع در بدنه کلاس معتبر میسازد.
کلاسهای عام بهطور ضمنی از Generic ارث میبرند. برای سازگاری با Python 3.11 و پایینتر، همچنین میتوان بهطور صریح از Generic ارث برد تا یک کلاس عام مشخص شود:
from typing import TypeVar, Generic
T = TypeVar('T')
class LoggedVar(Generic[T]):
...
کلاسهای عام دارای متد __class_getitem__() هستند، به این معنا که میتوانند در رانتایم پارامتریزه شوند (مثلاً LoggedVar[int] در زیر):
from collections.abc import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
یک نوع عام میتواند هر تعدادی از متغیرهای نوع داشته باشد. تمام گونههای TypeVar بهعنوان پارامتر برای یک نوع عام مجاز هستند:
from typing import TypeVar, Generic, Sequence
class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]:
...
OldT = TypeVar('OldT', contravariant=True)
OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True)
OldS = TypeVar('OldS', int, str)
class OldWeirdTrio(Generic[OldT, OldB, OldS]):
...
هر آرگومان متغیر نوع برای Generic باید متمایز باشد. بنابراین این نامعتبر است:
from typing import TypeVar, Generic
...
class Pair[M, M]: # SyntaxError
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
کلاسهای عام میتوانند از کلاسهای دیگر نیز ارثبری کنند:
from collections.abc import Sized
class LinkedList[T](Sized):
...
هنگام ارثبری از کلاسهای عام، برخی پارامترهای نوع میتوانند ثابت باشند:
from collections.abc import Mapping
class MyDict[T](Mapping[str, T]):
...
در این حالت MyDict تنها یک پارامتر دارد، T.
استفاده از یک کلاس عام بدون مشخص کردن پارامترهای نوع، برای هر جایگاه Any را فرض میکند. در مثال زیر، MyIterable عام نیست، اما بهطور ضمنی از Iterable[Any] ارث میبرد:
from collections.abc import Iterable
class MyIterable(Iterable): # Same as Iterable[Any]
...
نامهای مستعار نوع عام تعریفشده توسط کاربر نیز پشتیبانی میشوند. مثالها:
from collections.abc import Iterable
type Response[S] = Iterable[S] | int
# Return type here is same as Iterable[str] | int
def response(query: str) -> Response[str]:
...
type Vec[T] = Iterable[tuple[T, T]]
def inproduct[T: (int, float, complex)](v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]]
return sum(x*y for x, y in v)
برای سازگاری با عقبگرد، نامهای مستعار نوع عام را همچنین میتوان از طریق یک انتساب ساده ایجاد کرد:
from collections.abc import Iterable
from typing import TypeVar
S = TypeVar("S")
Response = Iterable[S] | int
تغییر یافته در نسخهی 3.7: Generic دیگر فراکلاس سفارشی ندارد.
تغییر یافته در نسخهی 3.12: پشتیبانی نحوی از عامسازی و نامهای مستعار نوع در نسخه 3.12 جدید است. پیش از این، کلاسهای عام باید بهصراحت از Generic ارثبری میکردند یا حاوی یک متغیر نوع در یکی از پایههای خود بودند.
عامهای تعریفشده توسط کاربر برای عبارات پارامتر نیز از طریق متغیرهای مشخصهی پارامتر در قالب [**P] پشتیبانی میشوند. این رفتار با رفتار متغیرهای نوع که در بالا توصیف شد، سازگار است، زیرا متغیرهای مشخصهی پارامتر توسط ماژول typing بهعنوان یک متغیر نوع تخصصی در نظر گرفته میشوند. تنها استثنا نسبت به این مورد این است که میتوان از فهرستی از انواع برای جایگزینی یک ParamSpec استفاده کرد:
>>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec
...
>>> Z[int, [dict, float]]
__main__.Z[int, [dict, float]]
کلاسهای عام روی یک ParamSpec را میتوان با ارثبری صریح از Generic نیز ایجاد کرد. در این حالت، از ** استفاده نمیشود:
from typing import ParamSpec, Generic
P = ParamSpec('P')
class Z(Generic[P]):
...
تفاوت دیگر بین TypeVar و ParamSpec این است که یک نوع عام با تنها یک متغیر مشخصکنندهی پارامتر، به دلایل زیبایی فهرستهای پارامتر را در قالبهای X[[Type1, Type2, ...]] و همچنین X[Type1, Type2, ...] میپذیرد. بهصورت داخلی، دومی به اولی تبدیل میشود، بنابراین موارد زیر معادل هستند:
>>> class X[**P]: ...
...
>>> X[int, str]
__main__.X[[int, str]]
>>> X[[int, str]]
__main__.X[[int, str]]
توجه داشته باشید که انواع عام با ParamSpec ممکن است در برخی موارد پس از جایگزینی، __parameters__ درستی نداشته باشند، زیرا عمدتاً برای بررسی ایستای نوع در نظر گرفته شدهاند.
تغییر یافته در نسخهی 3.10: اکنون میتوان Generic را روی عبارتهای پارامتری پارامتریزه کرد. برای جزئیات بیشتر، ParamSpec و PEP 612 را ببینید.
یک کلاس عام تعریفشده توسط کاربر میتواند ABCها را بهعنوان کلاسهای پایه داشته باشد، بدون آنکه تعارض فراکلاس رخ دهد. فراکلاسهای عام پشتیبانی نمیشوند. نتیجهی پارامترسازی عامها در نهانگاه ذخیره میشود، و بیشتر انواع در ماژول typing، hashable و قابل مقایسه از نظر برابری هستند.
نوع Any¶
Any گونهای خاص از نوع است. یک بررسیگر نوع ایستا، هر نوعی را قابل انتساب به Any و Any را قابل انتساب به هر نوعی در نظر میگیرد.
این بدان معناست که میتوان هر عملیات یا فراخوانی متد را روی مقداری از نوع Any انجام داد و آن را به هر متغیری انتساب داد:
from typing import Any
a: Any = None
a = [] # OK
a = 2 # OK
s: str = ''
s = a # OK
def foo(item: Any) -> int:
# Passes type checking; 'item' could be any type,
# and that type might have a 'bar' method
item.bar()
...
توجه کنید که هنگام انتساب یک مقدار از نوع Any به یک نوع دقیقتر، هیچ بررسی نوعی انجام نمیشود. برای مثال، بررسیکننده نوع ایستا هنگام انتساب a به s خطایی گزارش نکرد، با وجود اینکه s از نوع str اعلام شده بود و در رانتایم یک مقدار int دریافت میکند!
علاوه بر این، همه توابع بدون نوع بازگشتی یا انواع پارامترها، بهطور ضمنی بهصورت پیشفرض از Any استفاده خواهند کرد:
def legacy_parser(text):
...
return data
# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
...
return data
این رفتار به شما اجازه میدهد زمانی که نیاز دارید کد با نوعدهی پویا را با کد با نوعدهی ایستا ترکیب کنید، از Any بهعنوان یک راه فرار استفاده کنید.
رفتار Any را با رفتار object مقایسه کنید. مشابه Any، هر نوعی زیرنوعی از object است. با این حال، برخلاف Any، عکس آن درست نیست: object زیرنوع هر نوع دیگری نیست.
این بدان معناست که وقتی نوع یک مقدار object باشد، بررسیگر نوع تقریباً تمام عملیات روی آن را رد میکند و انتساب آن به یک متغیر (یا استفاده از آن بهعنوان مقدار بازگشتی) از نوعی تخصصیتر، خطای نوع است. برای مثال:
def hash_a(item: object) -> int:
# Fails type checking; an object does not have a 'magic' method.
item.magic()
...
def hash_b(item: Any) -> int:
# Passes type checking
item.magic()
...
# Passes type checking, since ints and strs are subclasses of object
hash_a(42)
hash_a("foo")
# Passes type checking, since Any is assignable to all types
hash_b(42)
hash_b("foo")
از object برای نشان دادن اینکه یک مقدار میتواند بهصورت ایمن از نظر نوع (typesafe) هر نوعی باشد، استفاده کنید. از Any برای نشان دادن اینکه یک مقدار دارای نوعدهی پویا است، استفاده کنید.
زیرنوعدهی اسمی در مقابل ساختاری¶
در ابتدا PEP 484 سیستم نوع ایستای پایتون را بهگونهای تعریف کرد که از زیرنوعدهی اسمی (nominal subtyping) استفاده میکند. این بدان معناست که کلاس A در هر جا که کلاس B انتظار میرود، اگر و فقط اگر A زیرکلاسی از B باشد، مجاز است.
این الزام پیشتر در مورد کلاسهای پایه انتزاعی، مانند Iterable نیز اعمال میشد. مشکل این رویکرد آن است که یک کلاس باید بهصراحت برای پشتیبانی از آنها علامتگذاری میشد، که غیرپایتونی است و برخلاف کاری است که معمولاً در کد پایتون ایدئوماتیک با نوعدهی پویا انجام میشود. برای مثال، این مورد با PEP 484 مطابقت دارد:
from collections.abc import Sized, Iterable, Iterator
class Bucket(Sized, Iterable[int]):
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
PEP 544 این مشکل را با امکان دادن به کاربران برای نوشتن کد بالا بدون کلاسهای پایه صریح در تعریف کلاس حل میکند و اجازه میدهد که Bucket توسط بررسیکنندههای نوع ایستا بهطور ضمنی یک زیرنوع از هر دو Sized و Iterable[int] در نظر گرفته شود. این بهعنوان زیرنوعدهی ساختاری (یا نوعدهی اردکی ایستا) شناخته میشود:
from collections.abc import Iterator, Iterable
class Bucket: # Note: no base classes
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect(items: Iterable[int]) -> int: ...
result = collect(Bucket()) # Passes type check
علاوه بر این، کاربر میتواند با زیرکلاسسازی از کلاس خاص Protocol، پروتکلهای سفارشی جدیدی تعریف کند تا بهطور کامل از زیرنوعدهی ساختاری (structural subtyping) بهرهمند شود (به مثالهای زیر مراجعه کنید).
محتویات ماژول¶
ماژول typing کلاسها، توابع و دکوراتورهای زیر را تعریف میکند.
اولیههای ویژه تایپ¶
انواع خاص¶
میتوان از این موارد بهعنوان نوعها در حاشیهنویسیها استفاده کرد. آنها از زیرنویسی با استفاده از [] پشتیبانی نمیکنند.
- typing.Any¶
نوع خاصی که نشاندهندهی یک نوع بدون محدودیت است.
تغییر یافته در نسخهی 3.11: اکنون میتوان از
Anyبهعنوان کلاس پایه استفاده کرد. این میتواند برای اجتناب از خطاهای بررسیکننده نوع در کلاسهایی که میتوانند در هر جایی نوعدهی اردکی شوند یا بسیار پویا هستند، مفید باشد.
- typing.AnyStr¶
-
تعریف:
AnyStr = TypeVar('AnyStr', str, bytes)
AnyStrبرای استفاده در توابعی در نظر گرفته شده است که ممکن است آرگومانهایstrیاbytesرا بپذیرند، اما نمیتوانند اجازه دهند این دو با هم ترکیب شوند.برای مثال:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat("foo", "bar") # OK, output has type 'str' concat(b"foo", b"bar") # OK, output has type 'bytes' concat("foo", b"bar") # Error, cannot mix str and bytes
توجه داشته باشید که
AnyStr، علیرغم نامش، هیچ ارتباطی با نوعAnyندارد و به معنای «هر رشتهای» نیز نیست. بهطور خاص،AnyStrوstr | bytesبا یکدیگر متفاوت هستند و موارد استفاده متفاوتی دارند:# Invalid use of AnyStr: # The type variable is used only once in the function signature, # so cannot be "solved" by the type checker def greet_bad(cond: bool) -> AnyStr: return "hi there!" if cond else b"greetings!" # The better way of annotating this function: def greet_proper(cond: bool) -> str | bytes: return "hi there!" if cond else b"greetings!"
منسوخ شده از نسخهی 3.13, در نسخهی 3.18 حذف خواهد شد: به نفع سینتکس پارامتر نوع جدید منسوخ شده است. بهجای ایمپورت کردن
AnyStr، ازclass A[T: (str, bytes)]: ...استفاده کنید. برای جزئیات بیشتر، PEP 695 را ببینید.در پایتون 3.16،
AnyStrازtyping.__all__حذف خواهد شد و در رانتایم، هنگام دسترسی به آن یا ایمپورت آن ازtyping، هشدارهای از رده خارج شدن نشان داده خواهند شد.AnyStrدر پایتون 3.18 ازtypingحذف خواهد شد.
- typing.LiteralString¶
نوع خاصی که فقط شامل رشتههای لفظی است.
هر لفظی رشتهای با
LiteralStringسازگار است، همانطور که یکLiteralStringدیگر نیز چنین است. با این حال، شیءای که فقط بهعنوانstrنوعدهی شده باشد، سازگار نیست. رشتهای که با ترکیب اشیای دارای نوعLiteralStringایجاد شده باشد نیز بهعنوانLiteralStringقابلقبول است.مثال:
def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: run_query("SELECT * FROM students") # OK run_query(literal_string) # OK run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" )
LiteralStringبرای APIهای حساسی مفید است که در آنها رشتههای دلخواه تولیدشده توسط کاربر ممکن است مشکلساز شوند. برای مثال، دو مورد بالا که باعث ایجاد خطاهای بررسیکننده نوع میشوند، ممکن است در برابر حمله تزریق SQL آسیبپذیر باشند.برای جزئیات بیشتر، PEP 675 را ببینید.
اضافه شده در نسخهی 3.11.
- typing.Never¶
- typing.NoReturn¶
NeverوNoReturnنوع پایینی (bottom type) را نشان میدهند، نوعی که هیچ عضوی ندارد.میتوان از آنها برای نشان دادن این موضوع استفاده کرد که یک تابع هرگز برنمیگردد، مانند
sys.exit():from typing import Never # or NoReturn def stop() -> Never: raise RuntimeError('no way')
یا برای تعریف تابعی که هرگز نباید فراخوانی شود، زیرا هیچ آرگومان معتبری وجود ندارد، مانند
assert_never():from typing import Never # or NoReturn def never_call_me(arg: Never) -> None: pass def int_or_str(arg: int | str) -> None: never_call_me(arg) # type checker error match arg: case int(): print("It's an int") case str(): print("It's a str") case _: never_call_me(arg) # OK, arg is of type Never (or NoReturn)
NeverوNoReturnدر سیستم نوع معنای یکسانی دارند و بررسیکنندههای نوع ایستا هر دو را بهطور معادل در نظر میگیرند.اضافه شده در نسخهی 3.6.2:
NoReturnاضافه شد.اضافه شده در نسخهی 3.11:
Neverاضافه شد.
- typing.Self¶
نوع خاصی برای نمایش کلاس دربرگیرندهی فعلی.
برای مثال:
from typing import Self, reveal_type class Foo: def return_self(self) -> Self: ... return self class SubclassOfFoo(Foo): pass reveal_type(Foo().return_self()) # Revealed type is "Foo" reveal_type(SubclassOfFoo().return_self()) # Revealed type is "SubclassOfFoo"
این حاشیهنویسی از نظر معنایی معادل مورد زیر است، هرچند بهشکلی مختصرتر:
from typing import TypeVar Self = TypeVar("Self", bound="Foo") class Foo: def return_self(self: Self) -> Self: ... return self
بهطور کلی، اگر چیزی
selfرا برمیگرداند، مانند مثالهای بالا، باید ازSelfبهعنوان حاشیهنویسی بازگشت استفاده کنید. اگرFoo.return_selfبهگونهای حاشیهنویسی شده باشد که"Foo"را برمیگرداند، آنگاه بررسیکننده نوع، شیء برگرداندهشده ازSubclassOfFoo.return_selfرا از نوعFooاستنباط میکند، نهSubclassOfFoo.از دیگر موارد استفادهی رایج میتوان به:
متدهای کلاس
classmethodکه بهعنوان سازندههای جایگزین استفاده میشوند و نمونههایی از پارامترclsرا برمیگردانند.حاشیهنویسی یک متد
__enter__()که self را برمیگرداند.
اگر تضمینی وجود ندارد که وقتی از کلاس زیرکلاس ساخته میشود، متد نمونهای از یک زیرکلاس را برگرداند، نباید از
Selfبهعنوان حاشیهنویسی بازگشت (return annotation) استفاده کنید:class Eggs: # Self would be an incorrect return annotation here, # as the object returned is always an instance of Eggs, # even in subclasses def returns_eggs(self) -> "Eggs": return Eggs()
برای جزئیات بیشتر، PEP 673 را ببینید.
اضافه شده در نسخهی 3.11.
- typing.TypeAlias¶
حاشیهنویسی ویژه برای اعلام صریح یک نام مستعار نوع.
برای مثال:
from typing import TypeAlias Factors: TypeAlias = list[int]
TypeAliasبهویژه در نسخههای قدیمیتر پایتون برای حاشیهنویسی نامهای مستعاری که از ارجاعهای پیشرو (forward references) استفاده میکنند، مفید است، زیرا ممکن است برای بررسیکنندههای نوع تشخیص این موارد از انتسابهای معمولی متغیر دشوار باشد:from typing import Generic, TypeAlias, TypeVar T = TypeVar("T") # "Box" does not exist yet, # so we have to use quotes for the forward reference on Python <3.12. # Using ``TypeAlias`` tells the type checker that this is a type alias declaration, # not a variable assignment to a string. BoxOfStrings: TypeAlias = "Box[str]" class Box(Generic[T]): @classmethod def make_box_of_strings(cls) -> BoxOfStrings: ...
برای جزئیات بیشتر، PEP 613 را ببینید.
اضافه شده در نسخهی 3.10.
منسوخ شده از نسخهی 3.12:
TypeAliasبه نفع دستورtypeمنسوخ شده است، که نمونههایی ازTypeAliasTypeایجاد میکند و بهصورت ذاتی از ارجاعهای پیشرو پشتیبانی میکند. توجه داشته باشید که با وجود اینکهTypeAliasوTypeAliasTypeاهداف مشابهی دارند و نامهای مشابهی دارند، این دو متمایز هستند و دومی نوع اولی نیست. در حال حاضر برنامهای برای حذفTypeAliasوجود ندارد، اما کاربران تشویق میشوند به دستوراتtypeمهاجرت کنند.
شکلهای خاص¶
این موارد میتوانند بهعنوان نوع در حاشیهنویسیها استفاده شوند. همهی آنها از زیرنویسی با [] پشتیبانی میکنند، اما هر کدام نحوِ یکتایی دارند.
- class typing.Union¶
نوع Union؛
Union[X, Y]معادلX | Yاست و به معنای X یا Y است.برای تعریف یک اجتماع (union)، برای نمونه از
Union[int, str]یا شکل کوتاهint | strاستفاده کنید. استفاده از آن شکل کوتاه توصیه میشود. جزئیات:آرگومانها باید نوع باشند و باید حداقل یکی وجود داشته باشد.
اجتماعهای تودرتو مسطح میشوند، برای مثال:
Union[Union[int, str], float] == Union[int, str, float]
با این حال، این موضوع در مورد اجتماعهای ارجاعشده از طریق یک نام مستعار نوع صدق نمیکند، تا از اجبار به ارزیابی
TypeAliasTypeزیرین جلوگیری شود:type A = Union[int, str] Union[A, float] != Union[int, str, float]
Unionهای با یک آرگومان حذف میشوند، مثلاً:
Union[int] == int # سازنده در واقع int را برمیگرداند
آرگومانهای زائد نادیده گرفته میشوند، برای مثال:
Union[int, str, int] == Union[int, str] == int | str
هنگام مقایسه اجتماعها (unions)، ترتیب آرگومانها نادیده گرفته میشود، برای مثال:
Union[int, str] == Union[str, int]
نمیتوانید از
Unionزیرکلاس بسازید یا آن را نمونهسازی کنید.شما نمیتوانید
Union[X][Y]را بنویسید.
تغییر یافته در نسخهی 3.7: زیرکلاسهای صریح را در رانتایم از اجتماعها (unions) حذف نکنید.
تغییر یافته در نسخهی 3.10: اکنون میتوان اجتماعها را بهصورت
X | Yنوشت. عبارات نوع اجتماعای را ببینید.تغییر یافته در نسخهی 3.14:
types.UnionTypeاکنون یک نام مستعار برایUnionاست، و هر دوUnion[int, str]وint | strنمونههایی از یک کلاس را ایجاد میکنند. برای بررسی اینکه آیا یک شیء در رانتایم یکUnionاست، ازisinstance(obj, Union)استفاده کنید. برای سازگاری با نسخههای پیشین پایتون، ازget_origin(obj) is typing.Union or get_origin(obj) is types.UnionTypeاستفاده کنید.
- typing.Optional¶
Optional[X]معادلX | None(یاUnion[X, None]) است.توجه داشته باشید که این مفهوم با آرگومان اختیاری یکسان نیست؛ آرگومان اختیاری آرگومانی است که مقدار پیشفرض دارد. یک آرگومان اختیاری دارای مقدار پیشفرض، فقط به این دلیل که اختیاری است، نیازی به مشخصکننده
Optionalدر حاشیهنویسی نوع خود ندارد. برای مثال:def foo(arg: int = 0) -> None: ...
از سوی دیگر، اگر مقدار صریح
Noneمجاز باشد، استفاده ازOptionalمناسب است، چه آرگومان اختیاری باشد و چه نباشد. برای مثال:def foo(arg: Optional[int] = None) -> None: ...
تغییر یافته در نسخهی 3.10: اکنون میتوان Optional را بهصورت
X | Noneنوشت. به عبارات نوع اجتماعی (union) مراجعه کنید.
- typing.Concatenate¶
شکل ویژه برای حاشیهنویسی توابع مرتبهبالاتر.
میتوان از
Concatenateبه همراه Callable وParamSpecبرای حاشیهنویسی یک فراخوانیپذیر مرتبه بالاتر استفاده کرد که پارامترهای یک فراخوانیپذیر دیگر را اضافه، حذف یا تبدیل میکند. نحوه استفاده به شکلConcatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]است.Concatenateزمانی معتبر است که در راهنماهای نوع Callable و هنگام نمونهسازی کلاسهای عام تعریفشده توسط کاربر با پارامترهایParamSpecاستفاده شود. آخرین پارامترConcatenateباید یکParamSpecیا سهنقطه (...) باشد.برای مثال، برای حاشیهنویسی یک دکوراتور
with_lockکه یکthreading.Lockرا در اختیار تابع دکوریتشده قرار میدهد، میتوان ازConcatenateاستفاده کرد تا نشان داده شود کهwith_lockیک شیء فراخوانیپذیر با امضای نوعی متفاوت برمیگرداند و انتظار یک شیء فراخوانیپذیر را دارد کهLockرا بهعنوان اولین آرگومان میگیرد. در این حالت،ParamSpecنشان میدهد که انواع پارامترهای شیء فراخوانیپذیر برگرداندهشده به انواع پارامترهای شیء فراخوانیپذیر ورودی وابسته است:from collections.abc import Callable from threading import Lock from typing import Concatenate # Use this lock to ensure that only one thread is executing a function # at any time. my_lock = Lock() def with_lock[**P, R](f: Callable[Concatenate[Lock, P], R]) -> Callable[P, R]: '''دکوراتوری ایمن از نظر نوع که یک قفل فراهم میکند.''' def inner(*args: P.args, **kwargs: P.kwargs) -> R: # Provide the lock as the first argument. return f(my_lock, *args, **kwargs) return inner @with_lock def sum_threadsafe(lock: Lock, numbers: list[float]) -> float: '''اعداد یک فهرست را بهصورت نخایمن با هم جمع میکند.''' with lock: return sum(numbers) # We don't need to pass in the lock ourselves thanks to the decorator. sum_threadsafe([1.1, 2.2, 3.3])
اضافه شده در نسخهی 3.10.
همچنین ملاحظه نمائید
PEP 612 -- متغیرهای مشخصسازی پارامتر (PEP معرفیکننده
ParamSpecوConcatenate)
- typing.Literal¶
شکل خاص نوعدهی برای تعریف «انواع لفظی» (literal types).
میتوان از
Literalاستفاده کرد تا به بررسیکنندههای نوع نشان داده شود که شیء حاشیهگذاریشده دارای مقداری معادل یکی از مقادیر لفظی ارائهشده است.برای مثال:
def validate_simple(data: Any) -> Literal[True]: # always returns True ... type Mode = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: Mode) -> str: ... open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checker
Literal[...]قابل زیرکلاسسازی نیست. در رانتایم، هر مقدار دلخواهی بهعنوان آرگومان نوع برایLiteral[...]مجاز است، اما بررسیکنندههای نوع ممکن است محدودیتهایی اعمال کنند. برای جزئیات بیشتر دربارهی انواع لفظی (literal types)، PEP 586 را ببینید.جزئیات بیشتر:
آرگومانها باید مقادیر لفظی باشند و باید دستکم یک آرگومان وجود داشته باشد.
انواع
Literalتودرتو تخت میشوند، مثلاً:assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]
با این حال، این موضوع در مورد انواع
Literalکه از طریق یک ناممستعار نوع به آنها ارجاع داده شدهاند اعمال نمیشود، تا از اجبار به ارزیابیTypeAliasTypeزیربنایی جلوگیری شود:type A = Literal[1, 2] assert Literal[A, 3] != Literal[1, 2, 3]
آرگومانهای زائد نادیده گرفته میشوند، برای مثال:
assert Literal[1, 2, 1] == Literal[1, 2]
هنگام مقایسهی مقادیر لفظی، ترتیب آرگومانها نادیده گرفته میشود، برای مثال:
assert Literal[1, 2] == Literal[2, 1]
شما نمیتوانید از
Literalزیرکلاس بسازید یا آن را نمونهسازی کنید.شما نمیتوانید
Literal[X][Y]را بنویسید.
اضافه شده در نسخهی 3.8.
- typing.ClassVar¶
ساختار نوع ویژه برای علامتگذاری متغیرهای کلاس.
همانطور که در PEP 526 معرفی شد، یک حاشیهنویسی متغیر که در ClassVar قرار گرفته باشد، نشان میدهد که یک ویژگی مشخص برای استفاده بهعنوان متغیر کلاس در نظر گرفته شده است و نباید روی نمونههای آن کلاس تنظیم شود. استفاده:
class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable
ClassVarفقط نوعها را میپذیرد و نمیتوان آن را بیشتر با کروشه پارامتردار (subscribed) کرد.ClassVarخودش یک کلاس نیست و نمیتوان از آن باisinstance()یاissubclass()استفاده کرد.ClassVarرفتار رانتایم پایتون را تغییر نمیدهد، اما بررسیکنندههای نوع ایستا میتوانند از آن استفاده کنند. برای مثال، ممکن است یک بررسیکننده نوع کد زیر را بهعنوان خطا علامتگذاری کند:enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OK
اضافه شده در نسخهی 3.5.3.
- typing.Final¶
ساختار ویژهی نوعدهی برای نشان دادن نامهای نهایی به بررسیکنندههای نوع.
نامهای نهایی را نمیتوان در هیچ محدودهای دوباره انتساب داد. نامهای نهایی اعلامشده در محدودههای کلاس را نمیتوان در زیرکلاسها بازنویسی کرد.
برای مثال:
MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Error reported by type checker class Connection: TIMEOUT: Final[int] = 10 class FastConnector(Connection): TIMEOUT = 1 # Error reported by type checker
هیچ بررسیای در رانتایم برای این ویژگیها انجام نمیشود. برای جزئیات بیشتر PEP 591 را ببینید.
اضافه شده در نسخهی 3.8.
- typing.Required¶
ساختار خاص تایپ برای علامتگذاری یک کلید در
TypedDictبهعنوان ضروری.این عمدتاً برای TypedDictهایی با
total=Falseمفید است. برای جزئیات بیشتر،TypedDictو PEP 655 را ببینید.اضافه شده در نسخهی 3.11.
- typing.NotRequired¶
ساختار خاص تایپینگ برای علامتگذاری یک کلید
TypedDictبهعنوان کلیدی که ممکن است موجود نباشد.برای جزئیات بیشتر
TypedDictو PEP 655 را ببینید.اضافه شده در نسخهی 3.11.
- typing.ReadOnly¶
یک ساختار خاص تایپینگ برای علامتگذاری یک آیتم از یک
TypedDictبهعنوان فقطخواندنی.برای مثال:
class Movie(TypedDict): title: ReadOnly[str] year: int def mutate_movie(m: Movie) -> None: m["year"] = 1999 # allowed m["title"] = "The Matrix" # type checker error
هیچ بررسیای در رانتایم برای این ویژگی وجود ندارد.
برای جزئیات بیشتر،
TypedDictو PEP 705 را ببینید.اضافه شده در نسخهی 3.13.
- typing.Annotated¶
شکل ویژهی نوعدهی برای افزودن فرادادهی مختص به زمینه به یک حاشیهنویسی .
با استفاده از حاشیهنویسی
Annotated[T, x]، فرادادهxرا به نوعTاضافه کنید. فرادادهی افزودهشده باAnnotatedمیتواند توسط ابزارهای تحلیل ایستا یا در رانتایم مورد استفاده قرار گیرد. در رانتایم، فراداده در ویژگی__metadata__ذخیره میشود.اگر یک کتابخانه یا ابزار با یک حاشیهنویسی
Annotated[T, x]مواجه شود و منطق خاصی برای فراداده نداشته باشد، باید فراداده را نادیده بگیرد و حاشیهنویسی را بهسادگی بهعنوانTدر نظر بگیرد. از این رو،Annotatedمیتواند برای کدی که میخواهد از حاشیهنویسیها برای اهدافی خارج از سیستم نوعدهی ایستای پایتون استفاده کند، مفید باشد.استفاده از
Annotated[T, x]بهعنوان یک حاشیهنویسی، همچنان امکان بررسی ایستای نوع برایTرا فراهم میکند، زیرا بررسیکنندههای نوع بهسادگی فرادادهیxرا نادیده میگیرند. به این ترتیب،Annotatedبا دکوراتور@no_type_checkتفاوت دارد، که میتواند برای افزودن حاشیهنویسیهایی خارج از محدودهی سیستم تایپ نیز استفاده شود، اما بررسی نوع را برای یک تابع یا کلاس بهطور کامل غیرفعال میکند.مسئولیت نحوه تفسیر فراداده بر عهده ابزار یا کتابخانهای است که با یک حاشیهنویسی
Annotatedمواجه میشود. ابزار یا کتابخانهای که با یک نوعAnnotatedمواجه میشود، میتواند عناصر فراداده را پیمایش کند تا تشخیص دهد که آیا آنها مورد توجه هستند یا خیر (برای مثال، با استفاده ازisinstance()).- Annotated[<type>, <metadata>]
در اینجا مثالی از نحوهی استفاده از
Annotatedبرای افزودن فراداده به حاشیهنویسیهای نوع، در صورتی که بخواهید تحلیل بازه انجام دهید، آمده است:@dataclass class ValueRange: lo: int hi: int T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)]
اولین آرگومان
Annotatedباید نوع معتبری باشد. از آنجا کهAnnotatedاز آرگومانهای با تعداد متغیر پشتیبانی میکند، میتوان چندین المان فراداده را فراهم کرد. ترتیب المانهای فراداده حفظ میشود و در بررسیهای برابری اهمیت دارد:@dataclass class ctype: kind: str a1 = Annotated[int, ValueRange(3, 10), ctype("char")] a2 = Annotated[int, ctype("char"), ValueRange(3, 10)] assert a1 != a2 # Order matters
تصمیمگیری دربارهی اینکه آیا کلاینت مجاز است چندین عنصر فراداده را به یک حاشیهنویسی اضافه کند و نحوهی ادغام آن حاشیهنویسیها، بر عهدهی ابزاری است که حاشیهنویسیها را مصرف میکند.
انواع
Annotatedتودرتو تخت میشوند. ترتیب عناصر فراداده از درونیترین حاشیهنویسی آغاز میشود:assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ int, ValueRange(3, 10), ctype("char") ]
با این حال، این مورد شامل انواع
Annotatedنمیشود که از طریق یک نام مستعار نوع به آنها ارجاع داده شده است، تا از اجبار به ارزیابیTypeAliasTypeزیربنایی جلوگیری شود:type From3To10[T] = Annotated[T, ValueRange(3, 10)] assert Annotated[From3To10[int], ctype("char")] != Annotated[ int, ValueRange(3, 10), ctype("char") ]
عناصر فرادادهی تکراری حذف نمیشوند:
assert Annotated[int, ValueRange(3, 10)] != Annotated[ int, ValueRange(3, 10), ValueRange(3, 10) ]
میتوان از
Annotatedهمراه با نامهای مستعار تودرتو و عام استفاده کرد:@dataclass class MaxLen: value: int type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)] # When used in a type annotation, a type checker will treat "V" the same as # ``Annotated[list[tuple[int, int]], MaxLen(10)]``: type V = Vec[int]
Annotatedرا نمیتوان با یکTypeVarTupleواگشاییشده استفاده کرد:type Variadic[*Ts] = Annotated[*Ts, Ann1] = Annotated[T1, T2, T3, ..., Ann1] # NOT valid
که در آن
T1،T2، ...TypeVarsهستند. این نامعتبر است، زیرا تنها یک نوع باید به Annotated داده شود.بهطور پیشفرض،
get_type_hints()فراداده را از حاشیهنویسیها حذف میکند.include_extras=Trueرا ارسال کنید تا فراداده حفظ شود:>>> from typing import Annotated, get_type_hints >>> def func(x: Annotated[int, "metadata"]) -> None: pass ... >>> get_type_hints(func) {'x': <class 'int'>, 'return': <class 'NoneType'>} >>> get_type_hints(func, include_extras=True) {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>}
در رانتایم، میتوان فرادادهی مرتبط با یک نوع
Annotatedرا از طریق ویژگی__metadata__بازیابی کرد:>>> from typing import Annotated >>> X = Annotated[int, "very", "important", "metadata"] >>> X typing.Annotated[int, 'very', 'important', 'metadata'] >>> X.__metadata__ ('very', 'important', 'metadata')
اگر میخواهید نوع اصلی پوشیدهشده با
Annotatedرا بازیابی کنید، از ویژگی__origin__استفاده کنید:>>> from typing import Annotated, get_origin >>> Password = Annotated[str, "secret"] >>> Password.__origin__ <class 'str'>
توجه داشته باشید که استفاده از
get_origin()خودAnnotatedرا برمیگرداند:>>> get_origin(Password) typing.Annotated
همچنین ملاحظه نمائید
- PEP 593 - حاشیهنویسیهای انعطافپذیر برای توابع و متغیرها
PEP معرفیکننده
Annotatedبه کتابخانه استاندارد.
اضافه شده در نسخهی 3.9.
- typing.TypeIs¶
ساختار خاص نوعدهی برای علامتگذاری توابع محمول نوع تعریفشده توسط کاربر.
میتوان از
TypeIsبرای حاشیهنویسی نوع بازگشتی یک تابع محمول نوع تعریفشده توسط کاربر استفاده کرد.TypeIsتنها یک آرگومان نوع میپذیرد. در رانتایم، توابعی که به این شکل حاشیهنویسی شدهاند باید یک مقدار بولی برگردانند و حداقل یک آرگومان جایگاهی دریافت کنند.TypeIsدر پی بهرهگیری از باریکسازی نوع (type narrowing) است -- روشی که بررسیکنندههای نوع ایستا برای تعیین نوع دقیقتر یک عبارت در جریان کد برنامه از آن استفاده میکنند. معمولاً باریکسازی نوع با تحلیل جریان کد شرطی و اعمال باریکسازی بر یک بلوک کد انجام میشود. در اینجا، عبارت شرطی گاهی «محمول نوع » نامیده میشود:def is_str(val: str | float): # "isinstance" type predicate if isinstance(val, str): # Type of ``val`` is narrowed to ``str`` ... else: # Else, type of ``val`` is narrowed to ``float``. ...
گاهی اوقات استفاده از یک تابع بولی تعریفشده توسط کاربر بهعنوان محمول نوع میتواند مناسب باشد. چنین تابعی باید از
TypeIs[...]یاTypeGuardبهعنوان نوع بازگشتی خود استفاده کند تا بررسیکنندههای نوع ایستا از این قصد آگاه شوند.TypeIsمعمولاً رفتاری شهودیتر ازTypeGuardدارد، اما زمانی که انواع ورودی و خروجی ناسازگار باشند (برای مثال،list[object]بهlist[int]) یا زمانی که تابع برای همه نمونههای نوع محدودشدهTrueرا برنمیگرداند، نمیتوان از آن استفاده کرد.استفاده از
-> TypeIs[NarrowedType]به بررسیکننده نوع ایستا میگوید که برای یک تابع مشخص:مقدار بازگشتی یک بولی است.
اگر مقدار بازگشتی
Trueباشد، نوع آرگومان آن برابر با اشتراک نوع اصلی آرگومان وNarrowedTypeاست.اگر مقدار بازگشتی
Falseباشد، نوع آرگومان آن محدود میشود تاNarrowedTypeرا شامل نشود.
برای مثال:
from typing import assert_type, final, TypeIs class Parent: pass class Child(Parent): pass @final class Unrelated: pass def is_parent(val: object) -> TypeIs[Parent]: return isinstance(val, Parent) def run(arg: Child | Unrelated): if is_parent(arg): # Type of ``arg`` is narrowed to the intersection # of ``Parent`` and ``Child``, which is equivalent to # ``Child``. assert_type(arg, Child) else: # Type of ``arg`` is narrowed to exclude ``Parent``, # so only ``Unrelated`` is left. assert_type(arg, Unrelated)
نوع درون
TypeIsباید با نوع آرگومان تابع سازگار باشد؛ در غیر این صورت، بررسیکنندههای نوع ایستا خطایی پرتاب میکنند. یک تابعTypeIsکه بهصورت نادرست نوشته شده باشد میتواند به رفتار ناسالم در سیستم نوع منجر شود؛ مسئولیت کاربر است که چنین توابعی را به شیوهای ایمن از نظر نوع بنویسد.اگر تابع
TypeIsیک متد کلاس یا متد نمونه باشد، نوع موجود درTypeIsبه نوع دومین پارامتر (پس ازclsیاself) نگاشت میشود.بهطور خلاصه، قالب
def foo(arg: TypeA) -> TypeIs[TypeB]: ...به این معناست که اگرfoo(arg)مقدارTrueرا برگرداند،argیک نمونه ازTypeBاست، و اگر مقدارFalseرا برگرداند، نمونهای ازTypeBنیست.TypeIsبا متغیرهای نوع نیز کار میکند. برای اطلاعات بیشتر، PEP 742 (باریکسازی انواع باTypeIs) را ببینید.اضافه شده در نسخهی 3.13.
- typing.TypeGuard¶
ساختار خاص نوعدهی برای علامتگذاری توابع محمول نوع تعریفشده توسط کاربر.
توابع محمول نوع، توابع تعریفشده توسط کاربر هستند که این را بازمیگردانند که آیا آرگومان خود نمونهای از یک نوع خاص است یا خیر.
TypeGuardمشابهTypeIsکار میکند، اما تأثیرات ظریف و متفاوتی بر رفتار بررسی نوع دارد (در زیر ببینید).استفاده از
-> TypeGuardبه بررسیگر نوع ایستا میگوید که برای یک تابع معین:مقدار بازگشتی یک بولی است.
اگر مقدار بازگشتی
Trueباشد، نوع آرگومان آن، نوع درونTypeGuardاست.
TypeGuardهمچنین با متغیرهای نوع کار میکند. برای جزئیات بیشتر، PEP 647 را ببینید.برای مثال:
def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Determines whether all objects in the list are strings''' return all(isinstance(x, str) for x in val) def func1(val: list[object]): if is_str_list(val): # Type of ``val`` is narrowed to ``list[str]``. print(" ".join(val)) else: # Type of ``val`` remains as ``list[object]``. print("Not a list of strings!")
TypeIsوTypeGuardبه روشهای زیر تفاوت دارند:TypeIsنیاز دارد که نوع محدودشده یک زیرنوع از نوع ورودی باشد، در حالی کهTypeGuardچنین الزامی ندارد. دلیل اصلی این است که امکان مواردی مانند محدود کردنlist[object]بهlist[str]فراهم شود، هرچند دومی زیرنوعی از اولی نیست، زیراlistناوردا است.هنگامی که یک تابع
TypeGuardمقدارTrueرا برمیگرداند، بررسیکنندههای نوع، نوع متغیر را دقیقاً به نوعTypeGuardمحدود میکنند. هنگامی که یک تابعTypeIsمقدارTrueرا برمیگرداند، بررسیکنندههای نوع میتوانند با ترکیب نوع از پیش شناختهشدهی متغیر با نوعTypeIs، نوع دقیقتری را استنتاج کنند. (از نظر فنی، به این نوع، نوع تقاطعی گفته میشود.)هنگامی که یک تابع
TypeGuardFalseرا برمیگرداند، بررسیکنندههای نوع بههیچوجه نمیتوانند نوع متغیر را محدودتر کنند. هنگامی که یک تابعTypeIsFalseرا برمیگرداند، بررسیکنندههای نوع میتوانند نوع متغیر را محدودتر کنند تا نوعTypeIsرا حذف کنند.
اضافه شده در نسخهی 3.10.
- typing.Unpack¶
عملگر تایپینگ برای نمادگذاری مفهومی یک شیء بهعنوان واگشاییشده.
برای مثال، استفاده از عملگر واگشایی
*بر روی یک تاپل متغیر نوع معادل استفاده ازUnpackبرای علامتگذاری آن تاپل متغیر نوع بهعنوان واگشاییشده است:Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Effectively does: tup: tuple[Unpack[Ts]]
در واقع، میتوان از
Unpackو*بهجای یکدیگر در زمینهی انواعtyping.TypeVarTupleوbuiltins.tupleاستفاده کرد. ممکن استUnpackرا بهصورت صریح در نسخههای قدیمیتر پایتون ببینید، یعنی در مواردی که امکان استفاده از*در برخی جایگاهها وجود نداشت:# In older versions of Python, TypeVarTuple and Unpack # are located in the `typing_extensions` backports package. from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Syntax error on Python <= 3.10! tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible
همچنین میتوان از
Unpackبه همراهtyping.TypedDictبرای نوعدهی**kwargsدر امضای تابع استفاده کرد:from typing import TypedDict, Unpack class Movie(TypedDict): name: str year: int # This function expects two keyword arguments - `name` of type `str` # and `year` of type `int`. def foo(**kwargs: Unpack[Movie]): ...
برای جزئیات بیشتر درباره استفاده از
Unpackبرای نوعدهی**kwargs، PEP 692 را ببینید.اضافه شده در نسخهی 3.11.
ساخت انواع عام و نامهای مستعار نوع¶
نباید از کلاسهای زیر بهصورت مستقیم بهعنوان حاشیهنویسی استفاده شود. هدف مورد نظر آنها این است که اجزای سازندهای برای ایجاد انواع عام و نامهای مستعار نوع باشند.
این اشیاء را میتوان از طریق سینتکس ویژه (فهرستهای پارامتر نوع و دستور type) ایجاد کرد. برای سازگاری با پایتون 3.11 و نسخههای پیش از آن، میتوان آنها را بدون سینتکس اختصاصی نیز ایجاد کرد، همانطور که در زیر مستند شده است.
- class typing.Generic¶
کلاس پایه انتزاعی برای انواع عام.
یک نوع عام معمولاً با افزودن فهرستی از پارامترهای نوع پس از نام کلاس تعریف میشود:
class Mapping[KT, VT]: def __getitem__(self, key: KT) -> VT: ... # Etc.
چنین کلاسی بهطور ضمنی از
Genericارثبری میکند. معنای رانتایمی این سینتکس در مرجع زبان بحث شده است.سپس میتوان از این کلاس بهصورت زیر استفاده کرد:
def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mapping[key] except KeyError: return default
در اینجا کروشههای پس از نام تابع نشاندهندهی یک تابع عام هستند.
برای سازگاری با عقبگرد، کلاسهای عام همچنین میتوانند با بهارثبری صریح از
Genericاعلام شوند. در این حالت، پارامترهای نوع باید بهصورت جداگانه اعلام شوند:KT = TypeVar('KT') VT = TypeVar('VT') class Mapping(Generic[KT, VT]): def __getitem__(self, key: KT) -> VT: ... # Etc.
- class typing.TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)¶
متغیر نوع.
روش ترجیحی برای ایجاد یک متغیر نوع، استفاده از سینتکس اختصاصی برای توابع عام، کلاسهای عام و نامهای مستعار نوع عام است:
class Sequence[T]: # T is a TypeVar ...
همچنین میتوان از این سینتکس برای ایجاد متغیرهای نوع کراندار و مقید استفاده کرد:
class StrSequence[S: str]: # S is a TypeVar with a `str` upper bound; ... # we can say that S is "bounded by `str`" class StrOrBytesSequence[A: (str, bytes)]: # A is a TypeVar constrained to str or bytes ...
با این حال، در صورت تمایل، متغیرهای نوع بازاستفادهپذیر را نیز میتوان بهصورت دستی ساخت، به این صورت:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
متغیرهای نوع عمدتاً برای کمک به بررسیکنندههای نوع ایستا وجود دارند. این متغیرها بهعنوان پارامترهایی برای انواع عام و همچنین برای تعاریف تابع عام و نام مستعار نوع به کار میروند. برای اطلاعات بیشتر درباره انواع عام،
Genericرا ببینید. توابع عام بهصورت زیر کار میکنند:def repeat[T](x: T, n: int) -> Sequence[T]: """Return a list containing n references to x.""" return [x]*n def print_capitalized[S: str](x: S) -> S: """Print x capitalized, and return x.""" print(x.capitalize()) return x def concatenate[A: (str, bytes)](x: A, y: A) -> A: """Add two strings or bytes objects together.""" return x + y
توجه داشته باشید که متغیرهای نوع میتوانند کراندار، مقید یا هیچکدام باشند، اما نمیتوانند همزمان هم کراندار و هم مقید باشند.
واریانس (variance) متغیرهای نوع، هنگامی که آنها از طریق سینتکس پارامتر نوع ایجاد میشوند یا هنگامی که
infer_variance=Trueارسال میشود، توسط بررسیکنندههای نوع استنتاج میشود. متغیرهای نوعی که بهصورت دستی ایجاد شدهاند، میتوانند با ارسالcovariant=Trueیاcontravariant=Trueبهصراحت بهعنوان هموردا یا پادوردا (contravariant) علامتگذاری شوند. بهطور پیشفرض، متغیرهای نوعی که بهصورت دستی ایجاد شدهاند، ناوردا (invariant) هستند. برای جزئیات بیشتر، PEP 484 و PEP 695 را ببینید.متغیرهای نوع کراندار و متغیرهای نوع مقید از چند جهت مهم معنای متفاوتی دارند. استفاده از یک متغیر نوع کراندار به این معناست که
TypeVarبا استفاده از خاصترین نوع ممکن حل میشود:x = print_capitalized('a string') reveal_type(x) # revealed type is str class StringSubclass(str): pass y = print_capitalized(StringSubclass('another string')) reveal_type(y) # revealed type is StringSubclass z = print_capitalized(45) # error: int is not a subtype of str
کران بالای یک متغیر نوع میتواند یک نوع عینی، نوع انتزاعی (ABC یا Protocol)، یا حتی اجتماعی از انواع باشد:
# Can be anything with an __abs__ method def print_abs[T: SupportsAbs](arg: T) -> None: print("Absolute value:", abs(arg)) U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method
با این حال، استفاده از یک متغیر نوع محدودشده به این معناست که
TypeVarفقط میتواند بهعنوان دقیقاً یکی از محدودیتهای دادهشده حل شود:a = concatenate('one', 'two') reveal_type(a) # revealed type is str b = concatenate(StringSubclass('one'), StringSubclass('two')) reveal_type(b) # revealed type is str, despite StringSubclass being passed in c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both
در رانتایم،
isinstance(x, T)استثنایTypeErrorرا پرتاب میکند.- __name__¶
نام متغیر نوع.
- __covariant__¶
اینکه آیا متغیر نوع بهصراحت بهعنوان هموردا علامتگذاری شده است یا خیر.
- __contravariant__¶
اینکه آیا متغیر نوع بهطور صریح بهعنوان پادوردا (contravariant) علامتگذاری شده است یا خیر.
- __infer_variance__¶
اینکه آیا واریانس متغیر نوع باید توسط بررسیکنندههای نوع استنباط شود.
اضافه شده در نسخهی 3.12.
- __bound__¶
کران بالای متغیر نوع، در صورت وجود.
تغییر یافته در نسخهی 3.12: برای متغیرهای نوعی که از طریق سینتکس پارامتر نوع ایجاد میشوند، کران تنها هنگامی ارزیابی میشود که به ویژگی دسترسی پیدا شود، نه هنگامی که متغیر نوع ایجاد میشود (به ارزیابی تنبل مراجعه کنید).
- evaluate_bound()¶
یک evaluate function متناظر با ویژگی
__bound__. هنگامی که این متد مستقیماً فراخوانی شود، فقط از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__bound__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()ارسال کرد تا مقدار را در قالب متفاوتی ارزیابی کند.اضافه شده در نسخهی 3.14.
- __constraints__¶
یک تاپل شامل محدودیتهای متغیر نوع، در صورت وجود.
تغییر یافته در نسخهی 3.12: برای متغیرهای نوعی که از طریق سینتکس پارامتر نوع ایجاد میشوند، محدودیتها فقط در زمان دسترسی به ویژگی ارزیابی میشوند، نه در زمان ایجاد متغیر نوع (به ارزیابی تنبل مراجعه کنید).
- evaluate_constraints()¶
یک evaluate function متناظر با ویژگی
__constraints__. هنگامی که این متد مستقیماً فراخوانی شود، تنها از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__constraints__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()پاس داد تا مقدار در قالبی متفاوت ارزیابی شود.اضافه شده در نسخهی 3.14.
- __default__¶
مقدار پیشفرض متغیر نوع، یا
typing.NoDefaultاگر پیشفرضی نداشته باشد.اضافه شده در نسخهی 3.13.
- evaluate_default()¶
یک تابع ارزیابی متناظر با ویژگی
__default__. هنگامی که این متد بهصورت مستقیم فراخوانی شود، تنها از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__default__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()ارسال کرد تا مقدار را در قالب دیگری ارزیابی کند.اضافه شده در نسخهی 3.14.
- has_default()¶
برمیگرداند که آیا متغیر نوع مقدار پیشفرض دارد یا خیر. این معادل بررسی این است که آیا
__default__تکنمونهtyping.NoDefaultنیست یا خیر، با این تفاوت که ارزیابی مقدار پیشفرضی که بهصورت تنبل ارزیابی میشود را تحمیل نمیکند.اضافه شده در نسخهی 3.13.
تغییر یافته در نسخهی 3.12: اکنون میتوان متغیرهای نوع را با استفاده از سینتکس پارامتر نوع که در PEP 695 معرفی شده است، اعلام کرد. پارامتر
infer_varianceافزوده شد.تغییر یافته در نسخهی 3.13: پشتیبانی از مقادیر پیشفرض اضافه شد.
- class typing.TypeVarTuple(name, *, default=typing.NoDefault)¶
تاپل متغیر نوع. شکل تخصصی از متغیر نوع که امکان عامهای چندآرگومانی (variadic) را فراهم میکند.
تاپلهای متغیر نوع را میتوان در فهرستهای پارامتر نوع با یک ستاره (
*) پیش از نام اعلام کرد:def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
یا با فراخوانی صریح سازندهی
TypeVarTuple:T = TypeVar("T") Ts = TypeVarTuple("Ts") def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
یک متغیر نوع عادی، امکان پارامتریسازی با یک نوع واحد را فراهم میکند. در مقابل، یک تاپل متغیر نوع مانند تعداد دلخواهی از متغیرهای نوع که در یک تاپل قرار گرفتهاند عمل میکند و امکان پارامتریسازی با تعداد دلخواهی از انواع را فراهم میکند. برای مثال:
# T is bound to int, Ts is bound to () # Return value is (1,), which has type tuple[int] move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,) # Return value is ('spam', 1), which has type tuple[str, int] move_first_element_to_last(tup=(1, 'spam')) # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) # This fails to type check (and fails at runtime) # because tuple[()] is not compatible with tuple[T, *Ts] # (at least one element is required) move_first_element_to_last(tup=())
به کاربرد عملگر واگشایی
*درtuple[T, *Ts]توجه کنید. از نظر مفهومی، میتوانیدTsرا تاپلی از متغیرهای نوع(T1, T2, ...)تصور کنید. در این صورتtuple[T, *Ts]بهtuple[T, *(T1, T2, ...)]تبدیل میشود، که معادلtuple[T, T1, T2, ...]است. (توجه داشته باشید که در نسخههای قدیمیتر پایتون، ممکن است این بهجای آن با استفاده ازUnpackنوشته شده باشد، بهصورتUnpack[Ts].)تاپلهای متغیر نوع (type variable tuples) باید همیشه واگشایی شوند. این امر به تمایز تاپلهای متغیر نوع از متغیرهای نوع معمولی کمک میکند:
x: Ts # Not valid x: tuple[Ts] # Not valid x: tuple[*Ts] # The correct way to do it
تاپلهای متغیر نوع (type variable tuples) میتوانند در همان زمینههایی استفاده شوند که متغیرهای نوع معمولی استفاده میشوند. برای مثال، در تعریف کلاسها، آرگومانها و انواع بازگشتی:
class Array[*Shape]: def __getitem__(self, key: tuple[*Shape]) -> float: ... def __abs__(self) -> "Array[*Shape]": ... def get_shape(self) -> tuple[*Shape]: ...
تاپلهای متغیر نوع میتوانند بهخوبی با متغیرهای نوع معمولی ترکیب شوند:
class Array[DType, *Shape]: # This is fine pass class Array2[*Shape, DType]: # This would also be fine pass class Height: ... class Width: ... float_array_1d: Array[float, Height] = Array() # Totally fine int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too
با این حال، توجه داشته باشید که حداکثر یک تاپل متغیر نوع (type variable tuple) میتواند در یک فهرست واحد از آرگومانهای نوع یا پارامترهای نوع ظاهر شود:
x: tuple[*Ts, *Ts] # Not valid class Array[*Shape, *Shape]: # Not valid pass
در نهایت، میتوان از یک متغیر نوع تاپلی واگشاییشده بهعنوان حاشیهنویسی نوع
*argsاستفاده کرد:def call_soon[*Ts]( callback: Callable[[*Ts], None], *args: *Ts ) -> None: ... callback(*args)
برخلاف حاشیهنویسیهای واگشایینشده برای
*args— مثلاً*args: int، که مشخص میکند همه آرگومانهاintهستند —*args: *Tsامکان ارجاع به انواع آرگومانهای تکی در*argsرا فراهم میکند. در اینجا، این امر به ما امکان میدهد اطمینان حاصل کنیم که انواع*argsارسالشده بهcall_soonبا انواع آرگومانهای (جایگاهی)callbackمطابقت دارند.برای جزئیات بیشتر درباره تاپلهای متغیر نوع، PEP 646 را ببینید.
- __name__¶
نام تاپل متغیر نوع.
- __default__¶
مقدار پیشفرض تاپل متغیر نوع، یا
typing.NoDefaultاگر پیشفرضی نداشته باشد.اضافه شده در نسخهی 3.13.
- evaluate_default()¶
یک evaluate function متناظر با ویژگی
__default__. هنگامی که این متد بهصورت مستقیم فراخوانی شود، تنها از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__default__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()ارسال کرد تا مقدار در قالبی متفاوت ارزیابی شود.اضافه شده در نسخهی 3.14.
- has_default()¶
بازگشت میدهد که آیا تاپل متغیر نوع دارای مقدار پیشفرض است یا خیر. این معادل بررسی این است که آیا
__default__تکنمونهیtyping.NoDefaultنیست یا خیر، با این تفاوت که ارزیابی مقدار پیشفرض بهصورت تنبل ارزیابیشده را اجباری نمیکند.اضافه شده در نسخهی 3.13.
اضافه شده در نسخهی 3.11.
تغییر یافته در نسخهی 3.12: اکنون میتوان تاپلهای متغیر نوع را با استفاده از سینتکس پارامتر نوع که در PEP 695 معرفیشده است، اعلام کرد.
تغییر یافته در نسخهی 3.13: پشتیبانی از مقادیر پیشفرض اضافه شد.
- class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False, infer_variance=False, default=typing.NoDefault)¶
متغیر مشخصات پارامتر. نسخهای تخصصی از متغیرهای نوع.
در فهرستهای پارامترهای نوع، میتوان مشخصههای پارامتر را با دو ستاره (
**) تعریف کرد:type IntFunc[**P] = Callable[P, int]
برای سازگاری با پایتون 3.11 و نسخههای قدیمیتر، میتوان اشیای
ParamSpecرا نیز بهصورت زیر ایجاد کرد:P = ParamSpec('P')
متغیرهای مشخصات پارامتر عمدتاً برای کمک به بررسیکنندههای نوع ایستا وجود دارند. آنها برای انتقال انواع پارامترهای یک فراخوانیپذیر به فراخوانیپذیر دیگر استفاده میشوند — الگویی رایج در توابع مرتبهی بالاتر و دکوراتورها. آنها تنها زمانی معتبر هستند که در
Concatenate، یا بهعنوان اولین آرگومانCallable، یا بهعنوان پارامترهایی برای انواع عام تعریفشده توسط کاربر استفاده شوند. برای اطلاعات بیشتر دربارهی انواع عام،Genericرا ببینید.برای مثال، برای افزودن گزارشگیری پایه به یک تابع، میتوان یک دکوراتور
add_loggingبرای ثبت فراخوانیهای تابع ایجاد کرد. متغیر مشخصه پارامتر به بررسیکننده نوع میگوید که شیء فراخوانیپذیرای که به دکوراتور داده میشود و شیء قابل فراخوانی جدیدی که توسط آن بازگردانده میشود، پارامترهای نوع وابسته به یکدیگر دارند:from collections.abc import Callable import logging def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]: '''A type-safe decorator to add logging to a function.''' def inner(*args: P.args, **kwargs: P.kwargs) -> T: logging.info(f'{f.__name__} was called') return f(*args, **kwargs) return inner @add_logging def add_two(x: float, y: float) -> float: '''Add two numbers together.''' return x + y
بدون
ParamSpec، سادهترین راه برای حاشیهنویسی این مورد پیشتر، استفاده از یکTypeVarبا کران بالاییCallable[..., Any]بود. با این حال این کار دو مشکل ایجاد میکند:بررسیگر نوع نمیتواند تابع
innerرا از نظر نوع بررسی کند، زیرا*argsو**kwargsباید بهصورتAnyنوعدهی شوند.ممکن است در بدنه دکوراتور
add_loggingهنگام برگرداندن تابعinner، استفاده ازcast()لازم باشد، یا باید به بررسیکننده نوع ایستا گفته شود کهreturn innerرا نادیده بگیرد.
- args¶
- kwargs¶
از آنجا که
ParamSpecهم پارامترهای جایگاهی و هم پارامترهای کلیدواژهای را در بر میگیرد، میتوان ازP.argsوP.kwargsبرای تجزیه یکParamSpecبه کامپوننتهای آن استفاده کرد.P.argsنشاندهنده تاپل پارامترهای جایگاهی در یک فراخوانی مشخص است و باید فقط برای حاشیهنویسی*argsبه کار رود.P.kwargsنشاندهنده نگاشت پارامترهای کلیدواژهای به مقادیرشان در یک فراخوانی مشخص است و باید فقط برای حاشیهنویسی**kwargsبه کار رود. هر دو ویژگی مستلزم آن هستند که پارامتر حاشیهنویسیشده در محدوده باشد. در رانتایم،P.argsوP.kwargsبهترتیب نمونههایی ازParamSpecArgsوParamSpecKwargsهستند.
- __name__¶
نام مشخصهی پارامتر.
- __default__¶
مقدار پیشفرض مشخصات پارامتر، یا
typing.NoDefaultاگر پیشفرضی نداشته باشد.اضافه شده در نسخهی 3.13.
- evaluate_default()¶
یک evaluate function متناظر با ویژگی
__default__. هنگام فراخوانی مستقیم، این متد تنها از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__default__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()ارسال کرد تا مقدار را در قالبی دیگر ارزیابی کند.اضافه شده در نسخهی 3.14.
- has_default()¶
بازمیگرداند که آیا مشخصهی پارامتر (parameter specification) مقدار پیشفرض دارد یا خیر. این معادل بررسی این است که آیا
__default__همان تکنمونهtyping.NoDefaultنیست، با این تفاوت که ارزیابی مقدار پیشفرض بهصورت تنبل ارزیابیشده را اجباری نمیکند.اضافه شده در نسخهی 3.13.
متغیرهای مشخصه پارامتر (parameter specification variables) ایجادشده با
covariant=Trueیاcontravariant=Trueمیتوانند برای اعلام انواع عام هموردا یا پادوردا (contravariant) استفاده شوند. آرگومانboundنیز پذیرفته میشود، مشابهTypeVar. با این حال، معنای واقعی این کلیدواژهها هنوز تعیین نشده است.اضافه شده در نسخهی 3.10.
تغییر یافته در نسخهی 3.12: اکنون میتوان مشخصات پارامتر را با استفاده از سینتکس پارامتر نوع معرفیشده در PEP 695 تعریف کرد.
تغییر یافته در نسخهی 3.13: پشتیبانی از مقادیر پیشفرض اضافه شد.
توجه
فقط متغیرهای مشخصه پارامتر تعریفشده در محدوده سراسری را میتوان پیکل کرد.
همچنین ملاحظه نمائید
PEP 612 -- متغیرهای مشخصسازی پارامتر (PEP معرفیکننده
ParamSpecوConcatenate)
- class typing.ParamSpecArgs¶
- class typing.ParamSpecKwargs¶
ویژگیهای آرگومانها و آرگومانهای کلیدواژهای یک
ParamSpec. ویژگیP.argsدر یکParamSpecنمونهای ازParamSpecArgsاست، وP.kwargsنمونهای ازParamSpecKwargsاست. آنها برای دروننگری در رانتایم در نظر گرفته شدهاند و معنای خاصی برای بررسیکنندههای نوع ایستا ندارند.فراخوانی
get_origin()برای هر یک از این اشیاء،ParamSpecاصلی را برمیگرداند:>>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True >>> get_origin(P.kwargs) is P True
اضافه شده در نسخهی 3.10.
- class typing.TypeAliasType(name, value, *, type_params=())¶
نوع نامهای مستعار نوع ایجادشده از طریق دستور
type.مثال:
>>> type Alias = int >>> type(Alias) <class 'typing.TypeAliasType'>
اضافه شده در نسخهی 3.12.
- __name__¶
نام مستعار نوع:
>>> type Alias = int >>> Alias.__name__ 'Alias'
- __module__¶
نام ماژولی که نام مستعار نوع در آن تعریف شده است:
>>> type Alias = int >>> Alias.__module__ '__main__'
- __type_params__¶
پارامترهای نوعِ نام مستعار نوع، یا یک تاپل خالی در صورتی که نام مستعار عام نباشد:
>>> type ListOrSet[T] = list[T] | set[T] >>> ListOrSet.__type_params__ (T,) >>> type NotGeneric = int >>> NotGeneric.__type_params__ ()
- __value__¶
مقدار نام مستعار نوع. این مقدار بهصورت تنبل ارزیابی میشود، بنابراین نامهای بهکاررفته در تعریف نام مستعار تا زمانی که به ویژگی
__value__دسترسی پیدا نشود، حل نمیشوند:>>> type Mutually = Recursive >>> type Recursive = Mutually >>> Mutually Mutually >>> Recursive Recursive >>> Mutually.__value__ Recursive >>> Recursive.__value__ Mutually
- evaluate_value()¶
یک evaluate function متناظر با ویژگی
__value__. هنگامی که این متد بهصورت مستقیم فراخوانی شود، فقط از قالبVALUEپشتیبانی میکند، که معادل دسترسی مستقیم به ویژگی__value__است، اما میتوان شیء متد را بهannotationlib.call_evaluate_function()ارسال کرد تا مقدار در قالبی متفاوت ارزیابی شود:>>> type Alias = undefined >>> Alias.__value__ Traceback (most recent call last): ... NameError: name 'undefined' is not defined >>> from annotationlib import Format, call_evaluate_function >>> Alias.evaluate_value(Format.VALUE) Traceback (most recent call last): ... NameError: name 'undefined' is not defined >>> call_evaluate_function(Alias.evaluate_value, Format.FORWARDREF) ForwardRef('undefined')
اضافه شده در نسخهی 3.14.
واگشایی
نامهای مستعار نوع از واگشایی ستارهای با استفاده از سینتکس
*Aliasپشتیبانی میکنند. این معادل استفاده مستقیم ازUnpack[Alias]است:>>> type Alias = tuple[int, str] >>> type Unpacked = tuple[bool, *Alias] >>> Unpacked.__value__ tuple[bool, typing.Unpack[Alias]]
اضافه شده در نسخهی 3.14.
سایر دایرکتیوهای خاص¶
این توابع و کلاسها نباید بهطور مستقیم بهعنوان حاشیهنویسی استفاده شوند. هدف موردنظر آنها این است که بلوکهای سازندهای برای ایجاد و اعلان انواع باشند.
- class typing.NamedTuple¶
نسخهی تایپشدهی
collections.namedtuple().استفاده:
class Employee(NamedTuple): name: str id: int
این معادل است با:
Employee = collections.namedtuple('Employee', ['name', 'id'])
برای دادن مقدار پیشفرض به یک فیلد، میتوانید در بدنه کلاس به آن مقدار اختصاص دهید:
class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') assert employee.id == 3
فیلدهای دارای مقدار پیشفرض باید پس از هر فیلد بدون مقدار پیشفرض قرار بگیرند.
میتوان نوع هر نام فیلد را با فراخوانی
annotationlib.get_annotations()بر روی کلاس حاصل بازیابی کرد. (نامهای فیلد در ویژگی_fieldsو مقادیر پیشفرض در ویژگی_field_defaultsقرار دارند، که هر دو بخشی از APInamedtuple()هستند.)زیرکلاسهای
NamedTupleهمچنین میتوانند رشتههای مستندسازی و متدها داشته باشند:class Employee(NamedTuple): """Represents an employee.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'
زیرکلاسهای
NamedTupleمیتوانند عام باشند:class Group[T](NamedTuple): key: T group: list[T]
استفادهی سازگار با نسخههای پیشین:
# For creating a generic NamedTuple on Python 3.11 T = TypeVar("T") class Group(NamedTuple, Generic[T]): key: T group: list[T] # A functional syntax is also supported Employee = NamedTuple('Employee', [('name', str), ('id', int)])
تغییر یافته در نسخهی 3.6: پشتیبانی از سینتکس حاشیهنویسی متغیرها در PEP 526 افزوده شد.
تغییر یافته در نسخهی 3.6.1: پشتیبانی از مقادیر پیشفرض، متدها و رشتهمستندها افزوده شد.
تغییر یافته در نسخهی 3.8: ویژگیهای
_field_typesو__annotations__اکنون بهجای نمونههایی ازOrderedDict، دیکشنریهای معمولی هستند.تغییر یافته در نسخهی 3.9: ویژگی
_field_typesبه نفع ویژگی استانداردتر__annotations__که همان اطلاعات را دارد، حذف شد.تغییر یافته در نسخهی 3.9:
NamedTupleاکنون بهجای کلاس، یک تابع است. هنوز میتوان از آن بهعنوان کلاس پایه استفاده کرد، همانطور که در بالا توضیح داده شد.تغییر یافته در نسخهی 3.11: پشتیبانی از namedtuples عام افزوده شد.
تغییر یافته در نسخهی 3.14: استفاده از
super()(و متغیر بستار با نام__class__) در متدهای زیرکلاسهایNamedTupleپشتیبانی نمیشود و منجر بهTypeErrorمیشود.منسوخ شده از نسخهی 3.13, در نسخهی 3.15 حذف خواهد شد: سینتکس آرگومان کلیدواژهای بدون مستند برای ایجاد کلاسهای NamedTuple (
NT = NamedTuple("NT", x=int)) منسوخ شده است و در 3.15 غیرمجاز خواهد شد. بهجای آن، از سینتکس مبتنی بر کلاس یا سینتکس تابعی استفاده کنید.منسوخ شده از نسخهی 3.13, در نسخهی 3.15 حذف خواهد شد: هنگام استفاده از سینتکس تابعی برای ایجاد یک کلاس NamedTuple، ارسال نکردن مقدار به پارامتر 'fields' (
NT = NamedTuple("NT")) منسوخ است. ارسالNoneبه پارامتر 'fields' (NT = NamedTuple("NT", None)) نیز منسوخ است. هر دو مورد در Python 3.15 غیرمجاز خواهند شد. برای ایجاد یک کلاس NamedTuple با ۰ فیلد، ازclass NT(NamedTuple): passیاNT = NamedTuple("NT", [])استفاده کنید.
- class typing.NewType(name, tp)¶
کلاس کمکی برای ایجاد انواع متمایز با سربار کم.
یک
NewTypeاز نظر یک بررسیگر نوع یک نوع متمایز در نظر گرفته میشود. با این حال، در رانتایم، فراخوانی یکNewTypeآرگومان خود را بدون تغییر برمیگرداند.استفاده:
UserId = NewType('UserId', int) # Declare the NewType "UserId" first_user = UserId(1) # "UserId" returns the argument unchanged at runtime
- __module__¶
نام ماژولی که نوع جدید در آن تعریف شده است.
- __name__¶
نام نوع جدید.
- __supertype__¶
نوعی که نوع جدید بر پایهی آن است.
اضافه شده در نسخهی 3.5.2.
تغییر یافته در نسخهی 3.10:
NewTypeاکنون یک کلاس است، نه یک تابع.
- class typing.Protocol(Generic)¶
کلاس پایه برای کلاسهای پروتکل.
کلاسهای پروتکل به این شکل تعریف میشوند:
class Proto(Protocol): def meth(self) -> int: ...
چنین کلاسهایی عمدتاً با بررسیکنندههای نوع ایستا استفاده میشوند که زیرنوعدهی ساختاری (نوعدهی اردکی ایستا) را به رسمیت میشناسند، برای مثال:
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check
برای جزئیات بیشتر PEP 544 را ببینید. کلاسهای پروتکل که با
@runtime_checkableآراسته شدهاند (بعداً توضیح داده میشود) بهعنوان پروتکلهای رانتایم سادهای عمل میکنند که تنها وجود ویژگیهای دادهشده را بررسی میکنند و امضاهای نوعی آنها را نادیده میگیرند. کلاسهای پروتکل بدون این دکوراتور نمیتوانند بهعنوان آرگومان دومisinstance()یاissubclass()استفاده شوند.کلاسهای Protocol میتوانند عام باشند، برای مثال:
class GenProto[T](Protocol): def meth(self) -> T: ...
در کدی که باید با Python 3.11 یا قدیمیتر سازگار باشد، میتوان پروتکلهای عام (generic Protocols) را بهصورت زیر نوشت:
T = TypeVar("T") class GenProto(Protocol[T]): def meth(self) -> T: ...
اضافه شده در نسخهی 3.8.
- @typing.runtime_checkable¶
یک کلاس پروتکل را بهعنوان پروتکل رانتایم علامتگذاری میکند.
چنین پروتکلی را میتوان با
isinstance()وissubclass()به کار برد. این امر یک بررسی ساختاری ساده را ممکن میسازد، که بسیار شبیه به «اسبهای تکفن» درcollections.abcمانندIterableاست. برای مثال:@runtime_checkable class Closable(Protocol): def close(self): ... assert isinstance(open('/some/file'), Closable) @runtime_checkable class Named(Protocol): name: str import threading assert isinstance(threading.Thread(name='Bob'), Named)
این دکوراتور هنگام اعمال روی یک کلاس غیرپروتکلی، استثنای
TypeErrorرا پرتاب میکند.توجه
@runtime_checkableفقط وجود متدها یا ویژگیهای مورد نیاز را بررسی میکند، نه امضای نوع یا نوع آنها را. برای مثال،ssl.SSLObjectیک کلاس است، بنابراین در بررسیissubclass()در برابر Callable قبول میشود. با این حال، متدssl.SSLObject.__init__فقط برای پرتاب یکTypeErrorبا پیامی آگاهکنندهتر وجود دارد، در نتیجه فراخوانی (نمونهسازی)ssl.SSLObjectرا غیرممکن میسازد.توجه
بررسی
isinstance()در برابر یک پروتکل قابلبررسی در رانتایم میتواند در مقایسه با بررسیisinstance()در برابر یک کلاس غیرپروتکلی بهطور غافلگیرکنندهای کند باشد. برای بررسیهای ساختاری در کد حساس به عملکرد، استفاده از الگوهای جایگزین مانند فراخوانیهایhasattr()را در نظر بگیرید.اضافه شده در نسخهی 3.8.
تغییر یافته در نسخهی 3.12: پیادهسازی داخلی بررسیهای
isinstance()در برابر پروتکلهای قابل بررسی در رانتایم، اکنون ازinspect.getattr_static()برای جستوجوی ویژگیها استفاده میکند (پیش از این،hasattr()استفاده میشد). در نتیجه، برخی اشیایی که پیشتر نمونههایی از یک پروتکل قابل بررسی در رانتایم در نظر گرفته میشدند، ممکن است دیگر در Python 3.12+ نمونههای آن پروتکل در نظر گرفته نشوند، و برعکس. بعید است بیشتر کاربران تحت تأثیر این تغییر قرار بگیرند.تغییر یافته در نسخهی 3.12: اعضای یک پروتکل قابلبررسی در رانتایم، اکنون بهمحض ایجاد کلاس، در رانتایم «فریز» در نظر گرفته میشوند. افزودن ویژگیها بهصورت مانکیپچ (monkey-patching) به یک پروتکل قابلبررسی در رانتایم همچنان کار میکند، اما هیچ تأثیری بر بررسیهای
isinstance()برای مقایسهی اشیاء با آن پروتکل نخواهد داشت. برای جزئیات بیشتر، تازههای پایتون 3.12 را ببینید.
- class typing.TypedDict(dict)¶
ساختاری ویژه برای افزودن راهنماهای نوع به یک دیکشنری. در رانتایم، «نمونههای
TypedDict» صرفاًdictsهستند.TypedDictیک نوع دیکشنری را تعریف میکند که انتظار دارد همه نمونههای آن دارای مجموعهای مشخص از کلیدها باشند، که هر کلید با مقداری از یک نوع سازگار مرتبط است. این انتظار در رانتایم بررسی نمیشود، بلکه فقط توسط بررسیکنندههای نوع اعمال میشود. کاربرد:class Point2D(TypedDict): x: int y: int label: str a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
یک روش جایگزین برای ایجاد
TypedDict، استفاده از سینتکس فراخوانی تابع است. آرگومان دوم باید یکdictلفظی باشد:Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
این سینتکس تابعی به شما امکان میدهد کلیدهایی را تعریف کنید که شناسههای معتبر نیستند، برای مثال به این دلیل که کلیدواژه هستند یا حاوی خط تیره هستند، یا زمانی که نام کلیدها نباید مانند نامهای خصوصی عادی دستکاری شوند:
# raises SyntaxError class Point2D(TypedDict): in: int # 'in' is a keyword x-y: int # name with hyphens class Definition(TypedDict): __schema: str # mangled to `_Definition__schema` # OK, functional syntax Point2D = TypedDict('Point2D', {'in': int, 'x-y': int}) Definition = TypedDict('Definition', {'__schema': str}) # not mangled
بهطور پیشفرض، تمام کلیدها باید در یک
TypedDictوجود داشته باشند. میتوان کلیدهای منفرد را با استفاده ازNotRequiredبهعنوان غیرضروری علامتگذاری کرد:class Point2D(TypedDict): x: int y: int label: NotRequired[str] # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})
این بدان معناست که یک
Point2DTypedDictمیتواند فاقد کلیدlabelباشد.همچنین میتوان با تعیین مقدار
Falseبرای totality، همهی کلیدها را بهطور پیشفرض بهعنوان غیرالزامی علامتگذاری کرد:class Point2D(TypedDict, total=False): x: int y: int # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)
این بدان معناست که یک
TypedDictاز نوعPoint2Dمیتواند فاقد هر یک از کلیدها باشد. انتظار میرود بررسیکننده نوع فقط از مقدار لفظیFalseیاTrueبهعنوان مقدار آرگومانtotalپشتیبانی کند.Trueمقدار پیشفرض است و تمام آیتمهای تعریفشده در بدنه کلاس را الزامی میکند.میتوان تکتک کلیدهای یک
TypedDictباtotal=Falseرا با استفاده ازRequiredبهعنوان الزامی علامتگذاری کرد:class Point2D(TypedDict, total=False): x: Required[int] y: Required[int] label: str # Alternative syntax Point2D = TypedDict('Point2D', { 'x': Required[int], 'y': Required[int], 'label': str }, total=False)
یک نوع
TypedDictمیتواند با استفاده از سینتکس مبتنی بر کلاس، از یک یا چند نوعTypedDictدیگر به ارث ببرد. استفاده:class Point3D(Point2D): z: int
Point3Dسه آیتم دارد:x،yوz. معادل این تعریف است:class Point3D(TypedDict): x: int y: int z: int
یک
TypedDictنمیتواند از کلاسی غیرTypedDictارثبری کند، بهجزGeneric. برای مثال:class X(TypedDict): x: int class Y(TypedDict): y: int class Z(object): pass # A non-TypedDict class class XY(X, Y): pass # OK class XZ(X, Z): pass # raises TypeError
یک
TypedDictمیتواند عام باشد:class Group[T](TypedDict): key: T group: list[T]
برای ایجاد یک
TypedDictعام که با Python 3.11 یا پایینتر سازگار است، بهصراحت ازGenericارثبری کنید:T = TypeVar("T") class Group(TypedDict, Generic[T]): key: T group: list[T]
یک
TypedDictرا میتوان از طریقannotationlib.get_annotations()(برای اطلاعات بیشتر درباره بهترین شیوههای حاشیهنویسی به بهترین شیوههای حاشیهنویسی مراجعه کنید) و ویژگیهای زیر دروننگری کرد:- __total__¶
Point2D.__total__مقدار آرگومانtotalرا میدهد. مثال:>>> from typing import TypedDict >>> class Point2D(TypedDict): pass >>> Point2D.__total__ True >>> class Point2D(TypedDict, total=False): pass >>> Point2D.__total__ False >>> class Point3D(Point2D): pass >>> Point3D.__total__ True
این ویژگی فقط مقدار آرگومان
totalبرای کلاسTypedDictجاری را نشان میدهد، نه اینکه آیا این کلاس از نظر معنایی total است یا خیر. برای مثال، یکTypedDictکه__total__آن رویTrueتنظیم شده است، ممکن است کلیدهایی داشته باشد که باNotRequiredعلامتگذاری شدهاند، یا ممکن است از یکTypedDictدیگر باtotal=Falseارثبری کند. بنابراین، بهطور کلی بهتر است برای دروننگری از__required_keys__و__optional_keys__استفاده کنید.
- __required_keys__¶
اضافه شده در نسخهی 3.9.
- __optional_keys__¶
Point2D.__required_keys__وPoint2D.__optional_keys__بهترتیب اشیایfrozensetشامل کلیدهای الزامی و غیرالزامی را بازمیگردانند.کلیدهای علامتگذاریشده با
Requiredهمیشه در__required_keys__ظاهر میشوند و کلیدهای علامتگذاریشده باNotRequiredهمیشه در__optional_keys__ظاهر میشوند.برای حفظ سازگاری با Python 3.10 و نسخههای پایینتر، همچنین میتوان از وراثت برای تعریف هر دو دسته کلید الزامی و غیرالزامی در یک
TypedDictواحد استفاده کرد. این کار با تعریف یکTypedDictبا یک مقدار برای آرگومانtotalو سپس وراثت از آن در یکTypedDictدیگر با مقداری متفاوت برایtotalانجام میشود:>>> class Point2D(TypedDict, total=False): ... x: int ... y: int ... >>> class Point3D(Point2D): ... z: int ... >>> Point3D.__required_keys__ == frozenset({'z'}) True >>> Point3D.__optional_keys__ == frozenset({'x', 'y'}) True
اضافه شده در نسخهی 3.9.
توجه
اگر از
from __future__ import annotationsاستفاده شود یا اگر حاشیهنویسیها بهصورت رشته ارائه شوند، حاشیهنویسیها هنگام تعریفTypedDictارزیابی نمیشوند. بنابراین، ممکن است دروننگری رانتایمی که__required_keys__و__optional_keys__به آن متکی هستند، بهدرستی کار نکند و مقادیر ویژگیها نادرست باشند.
پشتیبانی از
ReadOnlyدر ویژگیهای زیر بازتاب یافته است:- __readonly_keys__¶
یک
frozensetشامل نام تمام کلیدهای فقطخواندنی. کلیدها در صورتی فقطخواندنی هستند که دارای مشخصکننده (qualifier)ReadOnlyباشند.اضافه شده در نسخهی 3.13.
- __mutable_keys__¶
یک
frozensetحاوی نام تمام کلیدهای تغییرپذیر. کلیدها در صورتی تغییرپذیر هستند که فاقد مشخصکنندهReadOnlyباشند.اضافه شده در نسخهی 3.13.
برای مثالهای بیشتر و قوانین دقیق، بخش TypedDict را در مستندات typing ببینید.
اضافه شده در نسخهی 3.8.
تغییر یافته در نسخهی 3.9:
TypedDictاکنون بهجای کلاس، یک تابع است. هنوز هم میتوان از آن بهعنوان پایهی یک کلاس استفاده کرد، همانطور که در بالا توضیح داده شد.تغییر یافته در نسخهی 3.11: پشتیبانی از علامتگذاری کلیدهای منفرد بهعنوان
RequiredیاNotRequiredافزوده شد. PEP 655 را ببینید.تغییر یافته در نسخهی 3.11: پشتیبانی از
TypedDictهای عام افزوده شد.تغییر یافته در نسخهی 3.13: پشتیبانی از روش آرگومان کلیدواژهای برای ایجاد
TypedDicts حذف شد.تغییر یافته در نسخهی 3.13: پشتیبانی از مشخصکننده (qualifier)
ReadOnlyافزوده شد.منسوخ شده از نسخهی 3.13, در نسخهی 3.15 حذف خواهد شد: هنگام استفاده از سینتکس تابعی برای ایجاد یک کلاس TypedDict، عدم ارسال مقدار به پارامتر 'fields' (
TD = TypedDict("TD")) منسوخ شده است. ارسالNoneبه پارامتر 'fields' (TD = TypedDict("TD", None)) نیز منسوخ شده است. هر دو در Python 3.15 غیرمجاز خواهند شد. برای ایجاد یک کلاس TypedDict با ۰ فیلد، ازclass TD(TypedDict): passیاTD = TypedDict("TD", {})استفاده کنید.
پروتکلها¶
پروتکلهای زیر توسط ماژول typing ارائه شدهاند. همهی آنها با دکوراتور @runtime_checkable آراسته شدهاند.
- class typing.SupportsAbs¶
یک پروتکل با یک متد انتزاعی
__abs__که از نظر نوع بازگشتی، هموردا است.
- class typing.SupportsBytes¶
پروتکلی با یک متد انتزاعی
__bytes__.
- class typing.SupportsComplex¶
یک پروتکل با یک متد انتزاعی
__complex__.
- class typing.SupportsFloat¶
یک پروتکل با یک متد انتزاعی
__float__.
- class typing.SupportsIndex¶
یک پروتکل با یک متد انتزاعی
__index__.اضافه شده در نسخهی 3.8.
- class typing.SupportsInt¶
پروتکلی با یک متد انتزاعی
__int__.
- class typing.SupportsRound¶
یک پروتکل با یک متد انتزاعی
__round__که نوع بازگشتی آن هموردا است.
ABCها و پروتکلها برای کار با I/O¶
- class typing.IO[AnyStr]¶
- class typing.TextIO¶
- class typing.BinaryIO¶
کلاس عام
IO[AnyStr]و زیرکلاسهای آن،TextIO(IO[str])وBinaryIO(IO[bytes])، نشاندهندهی انواع جریانهای ورودی/خروجی هستند، مانند جریانهایی که توسطopen()بازگردانده میشوند. لطفاً توجه داشته باشید که این کلاسها پروتکل نیستند و رابط آنها نسبتاً گسترده است.
پروتکلهای io.Reader و io.Writer جایگزین سادهتری برای انواع آرگومان ارائه میدهند، هنگامی که بهترتیب فقط به متدهای read() یا write() دسترسی دارید:
def read_and_write(reader: Reader[str], writer: Writer[bytes]):
data = reader.read()
writer.write(data.encode())
همچنین برای تکرار روی سطرهای یک جریان ورودی، استفاده از collections.abc.Iterable را در نظر بگیرید:
def read_config(stream: Iterable[str]):
for line in stream:
...
توابع و دکوراتورها¶
- typing.cast(typ, val)¶
یک مقدار را به یک نوع تبدیل کنید.
این، مقدار را بدون تغییر برمیگرداند. برای بررسیگر نوع، این نشان میدهد که مقدار بازگشتی، نوع تعیینشده را دارد، اما در رانتایم عمداً هیچ چیزی را بررسی نمیکنیم (میخواهیم این تا حد ممکن سریع باشد).
- typing.assert_type(val, typ, /)¶
از یک بررسیکننده نوع ایستا بخواهید تأیید کند که نوع استنتاجشده برای val، typ است.
در رانتایم این هیچ کاری انجام نمیدهد: اولین آرگومان را بدون تغییر و بدون هیچگونه بررسی یا عوارض جانبی برمیگرداند، صرفنظر از نوع واقعی آرگومان.
هنگامی که یک بررسیکننده نوع ایستا با فراخوانی
assert_type()مواجه میشود، اگر مقدار از نوع مشخصشده نباشد، خطایی را نشان میدهد:def greet(name: str) -> None: assert_type(name, str) # OK, inferred type of `name` is `str` assert_type(name, int) # type checker error
این تابع برای اطمینان از هماهنگی درک بررسیکننده نوع از یک اسکریپت با قصد توسعهدهنده مفید است:
def complex_function(arg: object): # Do some complex type-narrowing logic, # after which we hope the inferred type will be `int` ... # Test whether the type checker correctly understands our function assert_type(arg, int)
اضافه شده در نسخهی 3.11.
- typing.assert_never(arg, /)¶
از یک بررسیگر نوع ایستا (static type checker) بخواهید تأیید کند که یک خط کد غیرقابلدسترس است.
مثال:
def int_or_str(arg: int | str) -> None: match arg: case int(): print("It's an int") case str(): print("It's a str") case _ as unreachable: assert_never(unreachable)
در اینجا، حاشیهنویسیها به بررسیگر نوع اجازه میدهند استنباط کند که آخرین حالت هرگز نمیتواند اجرا شود، زیرا
argیا یکintاست یا یکstr، و هر دو گزینه در حالتهای پیشین پوشش داده شدهاند.اگر یک بررسیکننده نوع تشخیص دهد که فراخوانی
assert_never()قابلدسترس است، خطایی نشان میدهد. برای مثال، اگر حاشیهنویسی نوع (type annotation) برایargدر عوضint | str | floatباشد، بررسیکننده نوع خطایی را نشان میدهد که نشان میدهدunreachableاز نوعfloatاست. برای این که فراخوانیassert_neverبررسی نوع را بگذراند، نوع استنتاجشده آرگومان دادهشده باید نوع پایین (bottom type)، یعنیNever، و نه هیچ چیز دیگری باشد.در رانتایم، این هنگام فراخوانی یک استثنا پرتاب میکند.
همچنین ملاحظه نمائید
کد غیرقابلدسترسی و بررسی جامعیت اطلاعات بیشتری درباره بررسی جامعیت با نوعدهی ایستا دارد.
اضافه شده در نسخهی 3.11.
- typing.reveal_type(obj, /)¶
از یک بررسیگر نوع ایستا بخواهید نوع استنتاجشدهی یک عبارت را آشکار کند.
هنگامی که یک بررسیکننده نوع ایستا با فراخوانی این تابع مواجه میشود، یک تشخیص همراه با نوع استنتاجشده آرگومان نشان میدهد. برای مثال:
x: int = 1 reveal_type(x) # Revealed type is "builtins.int"
این میتواند زمانی مفید باشد که بخواهید چگونگی برخورد بررسیکننده نوع خود با یک قطعه کد خاص را اشکالزدایی کنید.
در رانتایم، این تابع نوع رانتایمی آرگومان خود را در
sys.stderrچاپ میکند و آرگومان را بدون تغییر برمیگرداند (که اجازه میدهد فراخوانی درون یک عبارت به کار رود):x = reveal_type(1) # prints "Runtime type is int" print(x) # prints "1"
توجه داشته باشید که نوع رانتایم ممکن است با نوعی که یک بررسیکننده نوع بهصورت ایستا استنتاج میکند متفاوت باشد (خاصتر یا عامتر باشد).
بیشتر بررسیکنندههای نوع از
reveal_type()در هر جایی پشتیبانی میکنند، حتی اگر این نام ازtypingایمپورت نشده باشد. با این حال، ایمپورت کردن این نام ازtypingبه کد شما اجازه میدهد بدون خطاهای رانتایم اجرا شود و منظور را واضحتر بیان میکند.اضافه شده در نسخهی 3.11.
- @typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)¶
دکوراتوری برای علامتگذاری یک شیء بهعنوان ارائهدهندهی رفتاری شبیه به
dataclass.میتوان از
@dataclass_transformبرای دکور کردن یک کلاس، فراکلاس یا تابعی که خود یک دکوراتور است استفاده کرد. وجود@dataclass_transform()به یک بررسیگر نوع ایستا میگوید که شیء دکورشده «جادو»یی در رانتایم انجام میدهد که یک کلاس را به شیوهای مشابه@dataclasses.dataclassدگرگون میکند.نمونه استفاده با یک تابع دکوراتور:
@dataclass_transform() def create_model[T](cls: type[T]) -> type[T]: ... return cls @create_model class CustomerModel: id: int name: str
بر روی یک کلاس پایه:
@dataclass_transform() class ModelBase: ... class CustomerModel(ModelBase): id: int name: str
در یک فراکلاس:
@dataclass_transform() class ModelMeta(type): ... class ModelBase(metaclass=ModelMeta): ... class CustomerModel(ModelBase): id: int name: str
بررسیکنندههای نوع با کلاسهای
CustomerModelتعریفشده در بالا، مشابه کلاسهای ایجادشده با@dataclasses.dataclassرفتار خواهند کرد. برای مثال، بررسیکنندههای نوع فرض خواهند کرد که این کلاسها متدهای__init__دارند کهidوnameرا میپذیرند.کلاس، فراکلاس یا تابع دکوریتشده ممکن است آرگومانهای بولی زیر را بپذیرد که بررسیکنندههای نوع فرض خواهند کرد همان اثری را دارند که بر روی دکوراتور
@dataclasses.dataclassخواهند داشت:init،eq،order،unsafe_hash،frozen،match_args،kw_onlyوslots. باید بتوان مقدار این آرگومانها (TrueیاFalse) را بهصورت ایستا ارزیابی کرد.میتوان از آرگومانهای دکوراتور
@dataclass_transformبرای سفارشیسازی رفتارهای پیشفرض کلاس، فراکلاس یا تابع دکوراتشده استفاده کرد:- پارامترها:
eq_default (bool) -- نشان میدهد که اگر فراخواننده پارامتر
eqرا حذف کند، فرض میشود مقدار آنTrueیاFalseباشد. مقدار پیشفرض آنTrueاست.order_default (bool) -- نشان میدهد که اگر پارامتر
orderتوسط فراخواننده ذکر نشود، فرض میشود مقدار آنTrueباشد یاFalse. پیشفرضFalseاست.kw_only_default (bool) -- نشان میدهد که اگر فراخواننده پارامتر
kw_onlyرا حذف کند، این پارامترTrueفرض میشود یاFalse. مقدار پیشفرضFalseاست.frozen_default (bool) -- نشان میدهد که در صورت حذف پارامتر
frozenتوسط فراخواننده، آیاTrueفرض میشود یاFalse. پیشفرضFalseاست. .. versionadded:: 3.12field_specifiers (tuple[Callable[..., Any], ...]) -- فهرست ثابتی از کلاسها یا توابع پشتیبانیشده را مشخص میکند که فیلدها را توصیف میکنند، مشابه
dataclasses.field(). پیشفرض آن()است.**kwargs (Any) -- سایر آرگومانهای کلیدواژهای دلخواه پذیرفته میشوند تا امکان گسترشهای احتمالی در آینده فراهم شود.
بررسیکنندههای نوع، پارامترهای اختیاری زیر را در مشخصکنندههای فیلد شناسایی میکنند:
پارامترهای بهرسمیت شناختهشده برای مشخصکنندههای فیلد¶ نام پارامتر
توضیحات
initنشان میدهد که آیا فیلد باید در متد
__init__ساختهشده گنجانده شود یا خیر. اگر مشخص نشده باشد، پیشفرضinitبرابرTrueاست.defaultمقدار پیشفرض فیلد را فراهم میکند.
default_factoryیک کالبک رانتایم فراهم میکند که مقدار پیشفرض فیلد را برمیگرداند. اگر هیچکدام از
defaultوdefault_factoryمشخص نشده باشند، فرض میشود که فیلد مقدار پیشفرض ندارد و باید هنگام نمونهسازی کلاس، مقداری برای آن فراهم شود.factoryنام مستعاری برای پارامتر
default_factoryدر مشخصکنندههای فیلد.kw_onlyنشان میدهد که فیلد باید بهعنوان فقط کلیدواژهای علامتگذاری شود یا خیر. اگر
Trueباشد، فیلد فقط کلیدواژهای خواهد بود. اگرFalseباشد، فقط کلیدواژهای نخواهد بود. اگر تعیین نشده باشد، مقدار پارامترkw_onlyدر شیء آراستهشده با@dataclass_transformاستفاده میشود، یا اگر آن هم تعیین نشده باشد، مقدارkw_only_defaultدر@dataclass_transformاستفاده میشود.aliasنام جایگزینی برای فیلد فراهم میکند. این نام جایگزین در متد
__init__تولیدشده استفاده میشود.در رانتایم، این دکوراتور آرگومانهای خود را در ویژگی
__dataclass_transform__روی شیء دکوریتشده ثبت میکند. هیچ اثر دیگری در رانتایم ندارد.برای جزئیات بیشتر، PEP 681 را ببینید.
اضافه شده در نسخهی 3.11.
- @typing.overload¶
دکوراتور برای ایجاد توابع و متدهای سربارگذاریشده (overloaded).
دکوراتور
@overloadامکان توصیف توابع و متدهایی را فراهم میکند که از چندین ترکیب متفاوت از انواع آرگومان پشتیبانی میکنند. پس از مجموعهای از تعاریف آراستهشده با دکوراتور@overload، باید دقیقاً یک تعریف آراستهنشده با دکوراتور@overload(برای همان تابع/متد) بیاید.تعاریف دکورشده با
@overloadفقط برای بررسیکننده نوع در نظر گرفته شدهاند، زیرا تعریف بدون دکوراتور@overloadآنها را بازنویسی میکند. در مقابل، تعریف بدون دکوراتور@overloadدر رانتایم استفاده میشود، اما باید از سوی بررسیکننده نوع نادیده گرفته شود. در رانتایم، فراخوانی مستقیم یک تابع دکورشده با@overload،NotImplementedErrorرا پرتاب میکند.مثالی از سربارگذاری (overload) که نوع دقیقتری را نسبت به آنچه میتوان با استفاده از یک اجتماع (union) یا یک متغیر نوع بیان کرد، ارائه میدهد:
@overload def process(response: None) -> None: ... @overload def process(response: int) -> tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): ... # actual implementation goes here
برای جزئیات بیشتر و مقایسه با سایر معانی نوعدهی، PEP 484 را ببینید.
تغییر یافته در نسخهی 3.11: اکنون میتوان توابع سربارگذاریشده (overloaded) را در رانتایم با استفاده از
get_overloads()دروننگری کرد.
- typing.get_overloads(func)¶
دنبالهای از تعاریف آراستهشده با دکوراتور
@overloadبرای func برمیگرداند.func شیء تابع برای پیادهسازی تابع سربارگذاریشده (overload) است. برای مثال، با توجه به تعریف
processدر مستندات@overload،get_overloads(process)دنبالهای از سه شیء تابع برای سه اورلود تعریفشده را برمیگرداند. اگر برای تابعی بدون اورلود فراخوانی شود،get_overloads()دنبالهای خالی را برمیگرداند.میتوان از
get_overloads()برای دروننگری یک تابع سربارگذاریشده (overloaded function) در رانتایم استفاده کرد.اضافه شده در نسخهی 3.11.
- typing.clear_overloads()¶
تمام سربارگذاریهای (overloads) رجیستری داخلی را پاک میکند.
این میتواند برای آزادسازی حافظهی استفادهشده توسط رجیستری به کار رود.
اضافه شده در نسخهی 3.11.
- @typing.final¶
دکوراتوری برای مشخص کردن متدهای نهایی و کلاسهای نهایی.
اعمال دکوراتور
@finalبر یک متد، به یک بررسیکننده نوع نشان میدهد که نمیتوان آن متد را در یک زیرکلاس بازنویسی کرد. اعمال دکوراتور@finalبر یک کلاس، نشان میدهد که نمیتوان از آن زیرکلاس ساخت.برای مثال:
class Base: @final def done(self) -> None: ... class Sub(Base): def done(self) -> None: # Error reported by type checker ... @final class Leaf: ... class Other(Leaf): # Error reported by type checker ...
هیچ بررسیای در رانتایم برای این ویژگیها انجام نمیشود. برای جزئیات بیشتر PEP 591 را ببینید.
اضافه شده در نسخهی 3.8.
تغییر یافته در نسخهی 3.11: دکوراتور اکنون تلاش میکند ویژگی
__final__را روی شیء دکوریتشده بهTrueتنظیم کند. بنابراین، میتوان در رانتایم از بررسیای مانندif getattr(obj, "__final__", False)برای تعیین اینکه آیا یک شیءobjبهعنوان نهایی علامتگذاری شده است استفاده کرد. اگر شیء دکوریتشده از تنظیم ویژگیها پشتیبانی نکند، دکوراتور شیء را بدون تغییر و بدون پرتاب استثنا برمیگرداند.
- @typing.no_type_check¶
دکوراتوری برای نشان دادن اینکه حاشیهنویسیها راهنماییهای نوع نیستند.
این بهعنوان یک دکوراتور، آراینده برای کلاس یا تابع عمل میکند. در صورت استفاده برای یک کلاس، بهصورت بازگشتی به تمام متدها و کلاسهایی که در آن کلاس تعریف شدهاند اعمال میشود (اما به متدهایی که در کلاسهای والد یا زیرکلاسهای آن تعریف شدهاند اعمال نمیشود). بررسیکنندههای نوع تمام حاشیهنویسیهارا در یک تابع یا کلاس دارای این دکوراتور نادیده میگیرند.
@no_type_checkشیء دکوریتشده را بهصورت درجا تغییر میدهد.
- @typing.no_type_check_decorator¶
دکوراتوری که به دکوراتوری دیگر اثر
no_type_check()میدهد.این، دکوراتور را با چیزی میپوشاند که تابع دکوریتشده را در
no_type_check()میپوشاند.منسوخ شده از نسخهی 3.13, در نسخهی 3.15 حذف خواهد شد: تاکنون هیچ بررسیگر نوعی پشتیبانی از
@no_type_check_decoratorرا اضافه نکرده است. بنابراین منسوخ شده است و در پایتون 3.15 حذف خواهد شد.
- @typing.override¶
دکوراتوری برای نشان دادن این که یک متد در زیرکلاس برای بازنویسی یک متد یا ویژگی در ابرکلاس در نظر گرفته شده است.
بررسیکنندههای نوع باید در صورتی خطایی را نشان بدهند که یک متد آراستهشده با
@override، در واقع هیچ چیزی را بازنویسی نکند. این امر به پیشگیری از اشکالهایی کمک میکند که ممکن است هنگامی رخ دهند که یک کلاس پایه بدون تغییری معادل در یک کلاس فرزند تغییر داده شود.برای مثال:
class Base: def log_status(self) -> None: ... class Sub(Base): @override def log_status(self) -> None: # Okay: overrides Base.log_status ... @override def done(self) -> None: # Error reported by type checker ...
هیچ بررسیای در رانتایم برای این ویژگی انجام نمیشود.
دکوراتور تلاش میکند ویژگی
__override__را روی شیء دکوراتشده بهTrueتنظیم کند. بنابراین، میتوان از بررسیای مانندif getattr(obj, "__override__", False)در رانتایم استفاده کرد تا تعیین شود که آیا شیءobjبهعنوان بازنویسی علامتگذاری شده است یا خیر. اگر شیء دکوراتشده از تنظیم ویژگیها پشتیبانی نکند، دکوراتور شیء را بدون تغییر و بدون پرتاب استثنا برمیگرداند.برای جزئیات بیشتر به PEP 698 مراجعه کنید.
اضافه شده در نسخهی 3.12.
- @typing.type_check_only¶
دکوراتوری برای علامتگذاری یک کلاس یا تابع بهعنوان غیرقابلدسترس در رانتایم.
این دکوراتور به خودی خود در رانتایم در دسترس نیست. این دکوراتور عمدتاً برای علامتگذاری کلاسهایی در نظر گرفته شده است که در پروندههای stub نوع (type stub files) تعریف شدهاند، در صورتی که یک پیادهسازی، نمونهای از یک کلاس خصوصی را برگرداند:
@type_check_only class Response: # private or not available at runtime code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
توجه داشته باشید که برگرداندن نمونههای کلاسهای خصوصی توصیه نمیشود. معمولاً بهتر است چنین کلاسهایی عمومی شوند.
ابزارهای کمکی دروننگری¶
- typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False, *, format=Format.VALUE)¶
یک دیکشنری حاوی راهنماییهای نوع برای یک تابع، متد، ماژول، شیء کلاس، یا سایر اشیاء فراخوانیپذیر برمیگرداند.
این معمولاً همان
annotationlib.get_annotations()است، اما این تابع تغییرات زیر را در دیکشنری حاشیهنویسیها اعمال میکند:ارجاعهای پیشرو که بهصورت رشتههای لفظی یا اشیای
ForwardRefکدگذاری شدهاند، با ارزیابی آنها در globalns، localns و (در صورت لزوم) فضای نام پارامتر نوعobj رسیدگی میشوند. اگر globalns یا localns داده نشده باشد، دیکشنریهای فضای نام مناسب از obj استنتاج میشوند.Noneباtypes.NoneTypeجایگزین میشود.اگر
@no_type_checkبه obj اعمال شده باشد، یک دیکشنری خالی برگردانده میشود.اگر obj یک کلاس
Cباشد، تابع دیکشنریای را برمیگرداند که حاشیهگذاریهای کلاسهای پایهیCرا با حاشیهگذاریهایی که مستقیماً رویCقرار دارند، ادغام میکند. این کار با پیمایشC.__mro__و ترکیب تدریجی حاشیهگذاریها هر کلاس پایه انجام میشود. حاشیهگذاریهای کلاسهایی که زودتر در method resolution order ظاهر میشوند، همیشه بر حاشیهگذاریهای کلاسهایی که دیرتر در ترتیب حل متد ظاهر میشوند، اولویت دارند.این تابع بهصورت بازگشتی تمام موارد
Annotated[T, ...]،Required[T]،NotRequired[T]وReadOnly[T]را باTجایگزین میکند، مگر اینکه include_extras رویTrueتنظیم شده باشد (برای اطلاعات بیشترAnnotatedرا ببینید).
ملاحظه
این تابع ممکن است کد دلخواه موجود در حاشیهنویسیهارا اجرا کند. برای اطلاعات بیشتر، پیامدهای امنیتی دروننگری حاشیهنویسیها را ببینید.
توجه
اگر از
Format.VALUEاستفاده شود و هرگونه ارجاع پیشرو در حاشیهنویسیهای obj قابل حل نباشد، استثنایNameErrorپرتاب میشود. برای مثال، این ممکن است برای نامهایی رخ دهد که ذیلif TYPE_CHECKINGایمپورتشدهاند. بهطور کلیتر، اگر یک حاشیهنویسی حاوی کد نامعتبر پایتون باشد، ممکن است هر نوع استثنایی پرتاب شود.توجه
فراخوانی
get_type_hints()روی یک نمونه پشتیبانی نمیشود. برای بازیابی حاشیهنویسیهای یک نمونه، در عوضget_type_hints()را روی کلاس آن نمونه فراخوانی کنید (برای مثال،get_type_hints(type(obj))).تغییر یافته در نسخهی 3.9: پارامتر
include_extrasبهعنوان بخشی از PEP 593 اضافه شد. برای اطلاعات بیشتر، مستندات مربوط بهAnnotatedرا ببینید.تغییر یافته در نسخهی 3.11: پیشتر، اگر مقدار پیشفرض برابر با
Noneتنظیم شده بود،Optional[t]به annotationهای تابع و متد افزوده میشد. اکنون annotation بدون تغییر بازگردانده میشود.تغییر یافته در نسخهی 3.14: پارامتر
formatافزوده شد. برای اطلاعات بیشتر، مستنداتannotationlib.get_annotations()را ببینید.تغییر یافته در نسخهی 3.14: فراخوانی
get_type_hints()روی نمونهها دیگر پشتیبانی نمیشود. برخی از نمونهها در نسخههای پیشین بهعنوان جزئیات پیادهسازی بدون مستند پذیرفته میشدند.
- typing.get_origin(tp)¶
دریافت نسخهی بدون زیرنویس یک نوع: برای یک شیء typing به شکل
X[Y, Z, ...]،Xرا برمیگرداند.اگر
Xیک نام مستعار از ماژول typing برای یک کلاس توکار یا کلاسی ازcollectionsباشد، به کلاس اصلی نرمالسازی میشود. اگرXنمونهای ازParamSpecArgsیاParamSpecKwargsباشد،ParamSpecزیربنایی را برمیگرداند. برای اشیای پشتیبانینشده،Noneرا برمیگرداند.مثالها:
assert get_origin(str) is None assert get_origin(Dict[str, int]) is dict assert get_origin(Union[int, str]) is Union assert get_origin(Annotated[str, "metadata"]) is Annotated P = ParamSpec('P') assert get_origin(P.args) is P assert get_origin(P.kwargs) is P
اضافه شده در نسخهی 3.8.
- typing.get_args(tp)¶
آرگومانهای نوع را با تمام جایگزینیهای انجامشده دریافت میکند: برای یک شیء typing به فرم
X[Y, Z, ...]،(Y, Z, ...)را برمیگرداند.اگر
Xیک اجتماع (union) یاLiteralباشد که در یک نوع عام دیگر قرار گرفته است، ممکن است ترتیب(Y, Z, ...)به دلیل نهانگاه نوع با ترتیب آرگومانهای اصلی[Y, Z, ...]متفاوت باشد. برای اشیای پشتیبانینشده،()را برمیگرداند.مثالها:
assert get_args(int) == () assert get_args(Dict[int, str]) == (int, str) assert get_args(Union[int, str]) == (int, str)
اضافه شده در نسخهی 3.8.
- typing.get_protocol_members(tp)¶
مجموعهای از اعضای تعریفشده در یک
Protocolرا برمیگرداند.>>> from typing import Protocol, get_protocol_members >>> class P(Protocol): ... def a(self) -> str: ... ... b: int >>> get_protocol_members(P) == frozenset({'a', 'b'}) True
برای آرگومانهایی که پروتکل نیستند،
TypeErrorپرتاب میشود.اضافه شده در نسخهی 3.13.
- typing.is_protocol(tp)¶
تعیین میکند که آیا یک نوع، یک
Protocolاست یا خیر.برای مثال:
class P(Protocol): def a(self) -> str: ... b: int assert is_protocol(P) assert not is_protocol(int)
این تابع فقط برای کلاسهای
Protocolمقدار true را برمیگرداند، نه برای نامهای مستعار عام آنها:class GenericP[T](Protocol): def a(self) -> T: ... b: int assert not is_protocol(GenericP[int])
اضافه شده در نسخهی 3.13.
- typing.is_typeddict(tp)¶
بررسی کنید که آیا یک نوع،
TypedDictاست.برای مثال:
class Film(TypedDict): title: str year: int assert is_typeddict(Film) assert not is_typeddict(list | str) # TypedDict is a factory for creating typed dicts, # not a typed dict itself assert not is_typeddict(TypedDict)
این تابع فقط برای کلاسهای
TypedDictمقدار true را برمیگرداند، نه برای نامهای مستعار عام آنها:class GenericFilm[T](TypedDict): title: str year: T assert not is_typeddict(GenericFilm[int])
اضافه شده در نسخهی 3.10.
- class typing.ForwardRef¶
کلاسی که برای بازنمایی داخلی تایپِ ارجاعهای پیشروی رشتهای استفاده میشود.
برای مثال،
List["SomeClass"]بهطور ضمنی بهList[ForwardRef("SomeClass")]تبدیل میشود.ForwardRefنباید توسط کاربر نمونهسازی شود، اما ممکن است توسط ابزارهای دروننگری استفاده شود.توجه
انواع عام PEP 585 مانند
list["SomeClass"]بهطور ضمنی بهlist[ForwardRef("SomeClass")]تبدیل نمیشوند و بنابراین بهطور خودکار بهlist[SomeClass]حل نمیشوند.اضافه شده در نسخهی 3.7.4.
تغییر یافته در نسخهی 3.14: این اکنون نام مستعاری برای
annotationlib.ForwardRefاست. چندین رفتار مستندنشدهی این کلاس تغییر کرده است؛ برای مثال، پس از ارزیابی شدن یکForwardRef، مقدار ارزیابیشده دیگر در نهانگاه ذخیره نمیشود.
- typing.evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)¶
ارزیابی یک
annotationlib.ForwardRefبهعنوان یک type hint.این کار مشابه فراخوانی
annotationlib.ForwardRef.evaluate()است، اما برخلاف آن متد،evaluate_forward_ref()ارجاعهای پیشرو تودرتو درون راهنمای نوع را نیز بهصورت بازگشتی ارزیابی میکند.برای آگاهی از معنای پارامترهای owner، globals، locals، type_params و format، مستندات
annotationlib.ForwardRef.evaluate()را ببینید.ملاحظه
این تابع ممکن است کد دلخواه موجود در حاشیهنویسیهارا اجرا کند. برای اطلاعات بیشتر، پیامدهای امنیتی دروننگری حاشیهنویسیها را ببینید.
اضافه شده در نسخهی 3.14.
- typing.NoDefault¶
یک شیء نشانگر (sentinel) که برای نشان دادن این به کار میرود که یک پارامتر نوع مقدار پیشفرض ندارد. برای مثال:
>>> T = TypeVar("T") >>> T.__default__ is typing.NoDefault True >>> S = TypeVar("S", default=None) >>> S.__default__ is None True
اضافه شده در نسخهی 3.13.
ثابت¶
- typing.TYPE_CHECKING¶
ثابت ویژهای که بررسیکنندههای نوع ایستا آن را
Trueفرض میکنند. این ثابت در رانتایمFalseاست.ماژولی که ایمپورت آن پرهزینه است و فقط شامل انواع مورد استفاده برای حاشیهنویسیهای نوع است، میتواند بهصورت ایمن درون یک بلوک
if TYPE_CHECKING:ایمپورت شود. این کار از ایمپورت واقعی ماژول در رانتایم جلوگیری میکند؛ حاشیهنویسیها بهصورت فوری ارزیابی نمیشوند (به PEP 649 مراجعه کنید)، بنابراین استفاده از نمادهای تعریفنشده در حاشیهنویسیها بیضرر است—تا زمانی که بعداً آنها را بررسی نکنید. ابزار تحلیل ایستای نوع شما در طول تحلیل ایستای نوع،TYPE_CHECKINGرا رویTrueتنظیم میکند، که به این معناست که ماژول ایمپورت خواهد شد و انواع در طول چنین تحلیلی بهدرستی بررسی خواهند شد.استفاده:
if TYPE_CHECKING: import expensive_mod def fun(arg: expensive_mod.SomeType) -> None: local_var: expensive_mod.AnotherType = other_fun()
اگر گاهی نیاز دارید حاشیهنویسیهای نوعی را که ممکن است حاوی نمادهای تعریفنشده باشند در رانتایم بررسی کنید، از
annotationlib.get_annotations()با پارامترformatبا مقدارannotationlib.Format.STRINGیاannotationlib.Format.FORWARDREFاستفاده کنید تا حاشیهنویسیها را بدون پرتابNameErrorبهصورت امن بازیابی کنید.اضافه شده در نسخهی 3.5.2.
نامهای مستعار منسوخ¶
این ماژول چندین نام مستعار منسوخ به کلاسهای از پیش موجود در کتابخانه استاندارد را تعریف میکند. این نامهای مستعار در ابتدا در ماژول typing گنجانده شده بودند تا از پارامتریزه کردن این کلاسهای عام با استفاده از [] پشتیبانی کنند. با این حال، این نامهای مستعار در پایتون 3.9 زائد شدند؛ هنگامی که کلاسهای از پیش موجود متناظر برای پشتیبانی از [] بهبود یافتند (به PEP 585 مراجعه کنید).
انواع زائد از پایتون 3.9 منسوخ شدهاند. هرچند ممکن است این نامهای مستعار در مقطعی حذف شوند، اما حذف آنها در حال حاضر برنامهریزی نشده است. بنابراین، در حال حاضر هیچ هشداری برای از رده خارج شدن این نامهای مستعار از سوی مفسر نشان داده نمیشود.
اگر در مقطعی تصمیم به حذف این نامهای مستعار منسوخ گرفته شود، مفسر حداقل در دو نسخهی پیش از حذف، هشدار از رده خارج شدن نشان خواهد داد. تضمین میشود که این نامهای مستعار در ماژول typing بدون هشدار از رده خارج شدن، حداقل تا پایتون 3.14 باقی بمانند.
بررسیکنندههای نوع تشویق میشوند که در صورتی که برنامهای که آن را بررسی میکنند حداقل نسخهی پایتون 3.9 یا جدیدتر را هدف قرار دهد، موارد استفاده از انواع منسوخ را نمادگذاری کنند.
نامهای مستعار برای انواع توکار¶
- class typing.Dict(dict, MutableMapping[KT, VT])¶
نام مستعار منسوخشده برای
dict.توجه داشته باشید که برای حاشیهنویسی آرگومانها، ترجیح داده میشود از یک نوع مجموعه انتزاعی مانند
Mappingاستفاده شود، نه ازdictیاtyping.Dict.منسوخ شده از نسخهی 3.9:
builtins.dictاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.List(list, MutableSequence[T])¶
نام مستعار منسوخشده برای
list.توجه داشته باشید که برای حاشیهنویسی آرگومانها، ترجیح داده میشود به جای استفاده از
listیاtyping.Listاز یک نوع مجموعه انتزاعی مانندSequenceیاIterableاستفاده شود.منسوخ شده از نسخهی 3.9:
builtins.listاکنون از زیرنویسی (subscripting) با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Set(set, MutableSet[T])¶
نام مستعار منسوخشده برای
builtins.set.توجه کنید که برای حاشیهنویسی کردن آرگومانها، ترجیح داده میشود بهجای استفاده از
setیاtyping.Set، از یک نوع مجموعهی انتزاعی مانندcollections.abc.Setاستفاده شود.منسوخ شده از نسخهی 3.9:
builtins.setاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.FrozenSet(frozenset, AbstractSet[T_co])¶
نام مستعار منسوخ برای
builtins.frozenset.منسوخ شده از نسخهی 3.9:
builtins.frozensetاکنون از اندیسگذاری ([]) پشتیبانی میکند. به PEP 585 و Generic Alias Type مراجعه کنید.
- typing.Tuple¶
نام مستعار منسوخ برای
tuple.tupleوTupleدر سیستم نوع حالت خاصی دارند؛ برای جزئیات بیشتر، حاشیهنویسی تاپلها را ببینید.منسوخ شده از نسخهی 3.9:
builtins.tupleاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Type(Generic[CT_co])¶
نام مستعار منسوخ برای
type.برای جزئیات درباره استفاده از
typeیاtyping.Typeدر حاشیهنویسیهای نوع، نوع اشیای کلاس را ببینید.اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.9:
builtins.typeاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
نامهای مستعار برای نوعها در collections¶
- class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])¶
نام مستعار منسوخشده برای
collections.defaultdict.اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.9:
collections.defaultdictاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])¶
نام مستعار منسوخشده برای
collections.OrderedDict.اضافه شده در نسخهی 3.7.2.
منسوخ شده از نسخهی 3.9:
collections.OrderedDictاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])¶
نام مستعار منسوخ برای
collections.ChainMap.اضافه شده در نسخهی 3.6.1.
منسوخ شده از نسخهی 3.9:
collections.ChainMapاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Counter(collections.Counter, Dict[T, int])¶
نام مستعار منسوخشده برای
collections.Counter.اضافه شده در نسخهی 3.6.1.
منسوخ شده از نسخهی 3.9:
collections.Counterاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Deque(deque, MutableSequence[T])¶
نام مستعار منسوخشده برای
collections.deque.اضافه شده در نسخهی 3.6.1.
منسوخ شده از نسخهی 3.9:
collections.dequeاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
نامهای مستعار برای سایر انواع مشخص¶
- class typing.Pattern¶
- class typing.Match¶
نامهای مستعار منسوخشدهی متناظر با انواع بازگشتی از
re.compile()وre.match().این انواع (و توابع متناظر) نسبت به
AnyStrعام هستند.Patternمیتواند بهصورتPattern[str]یاPattern[bytes]تخصصی شود؛Matchمیتواند بهصورتMatch[str]یاMatch[bytes]تخصصی شود.منسوخ شده از نسخهی 3.9: کلاسهای
PatternوMatchازreاکنون از[]پشتیبانی میکنند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Text¶
نام مستعار منسوخشده برای
str.Textبرای فراهم کردن مسیری سازگار با آینده برای کد پایتون 2 ارائه شده است: در پایتون 2،Textنام مستعاری برایunicodeاست.برای نشان دادن اینکه یک مقدار باید حاوی یک رشتهی یونیکد بهشکلی سازگار با هر دو Python 2 و Python 3 باشد، از
Textاستفاده کنید:def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.11: Python 2 دیگر پشتیبانی نمیشود، و بیشتر بررسیکنندههای نوع نیز دیگر از بررسی نوع کد Python 2 پشتیبانی نمیکنند. حذف این نام مستعار در حال حاضر برنامهریزی نشده است، اما به کاربران توصیه میشود بهجای
Textازstrاستفاده کنند.
نامهای مستعار برای ABCهای ظرف در collections.abc¶
- class typing.AbstractSet(Collection[T_co])¶
نام مستعار منسوخشده برای
collections.abc.Set.منسوخ شده از نسخهی 3.9:
collections.abc.Setاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.ByteString(Sequence[int])¶
نام مستعار منسوخ برای
collections.abc.ByteString.برای بررسی اینکه آیا
objپروتکل بافر را در رانتایم پیادهسازی میکند، ازisinstance(obj, collections.abc.Buffer)استفاده کنید. برای استفاده در حاشیهنویسیهای نوع، یا ازBufferاستفاده کنید یا از یک اجتماع (union) که بهصراحت نوعهایی را که کد شما از آنها پشتیبانی میکند مشخص میکند (مثلاًbytes | bytearray | memoryview).ByteStringدر ابتدا قرار بود یک کلاس انتزاعی باشد که بهعنوان ابرنوع هر دوbytesوbytearrayعمل کند. با این حال، از آنجا که این ABC هرگز هیچ متدی نداشت، دانستن اینکه یک شیء نمونهای ازByteStringاست، هرگز در عمل اطلاعات مفیدی درباره آن شیء به شما نمیداد. سایر انواع رایج بافر مانندmemoryviewنیز هرگز بهعنوان زیرنوعهایی ازByteStringشناخته نمیشدند (چه در رانتایم و چه از سوی بررسیکنندههای نوع ایستا).برای جزئیات بیشتر، PEP 688 را ببینید.
منسوخ شده از نسخهی 3.9, در نسخهی 3.17 حذف خواهد شد.
- class typing.Collection(Sized, Iterable[T_co], Container[T_co])¶
نام مستعار منسوخشده برای
collections.abc.Collection.اضافه شده در نسخهی 3.6.
منسوخ شده از نسخهی 3.9:
collections.abc.Collectionاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Container(Generic[T_co])¶
نام مستعار منسوخ برای
collections.abc.Container.منسوخ شده از نسخهی 3.9:
collections.abc.Containerاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])¶
نام مستعار منسوخ برای
collections.abc.ItemsView.منسوخ شده از نسخهی 3.9:
collections.abc.ItemsViewاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.KeysView(MappingView, AbstractSet[KT_co])¶
نام مستعار منسوخ برای
collections.abc.KeysView.منسوخ شده از نسخهی 3.9:
collections.abc.KeysViewاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Mapping(Collection[KT], Generic[KT, VT_co])¶
نام مستعار منسوخ برای
collections.abc.Mapping.منسوخ شده از نسخهی 3.9:
collections.abc.Mappingاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.MappingView(Sized)¶
نام مستعار منسوخ برای
collections.abc.MappingView.منسوخ شده از نسخهی 3.9:
collections.abc.MappingViewاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.MutableMapping(Mapping[KT, VT])¶
نام مستعار منسوخشده برای
collections.abc.MutableMapping.منسوخ شده از نسخهی 3.9:
collections.abc.MutableMappingاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.MutableSequence(Sequence[T])¶
نام مستعار منسوخشده برای
collections.abc.MutableSequence.منسوخ شده از نسخهی 3.9:
collections.abc.MutableSequenceاکنون از اندیسدهی با[]پشتیبانی میکند. به PEP 585 و Generic Alias Type مراجعه کنید.
- class typing.MutableSet(AbstractSet[T])¶
نام مستعار منسوخشده برای
collections.abc.MutableSet.منسوخ شده از نسخهی 3.9:
collections.abc.MutableSetاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Sequence(Reversible[T_co], Collection[T_co])¶
نام مستعار منسوخشده برای
collections.abc.Sequence.منسوخ شده از نسخهی 3.9:
collections.abc.Sequenceاکنون از اندیسدهی ([]) پشتیبانی میکند. به PEP 585 و Generic Alias Type مراجعه کنید.
- class typing.ValuesView(MappingView, Collection[_VT_co])¶
نام مستعار منسوخ برای
collections.abc.ValuesView.منسوخ شده از نسخهی 3.9:
collections.abc.ValuesViewاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
نامهای مستعار برای کلاسهای پایه انتزاعی ناهمگام (ABC) در collections.abc¶
- class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])¶
نام مستعار منسوخشده برای
collections.abc.Coroutine.برای جزئیات در مورد استفاده از
collections.abc.Coroutineوtyping.Coroutineدر حاشیهنویسیهای نوع، حاشیهنویسی تولیدگرها و همروالها را ببینید.اضافه شده در نسخهی 3.5.3.
منسوخ شده از نسخهی 3.9:
collections.abc.Coroutineاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])¶
نام مستعار منسوخ برای
collections.abc.AsyncGenerator.برای جزئیات درباره استفاده از
collections.abc.AsyncGeneratorوtyping.AsyncGeneratorدر حاشیهنویسیهای نوع، حاشیهنویسی تولیدگرها و همروالها را ببینید.اضافه شده در نسخهی 3.6.1.
منسوخ شده از نسخهی 3.9:
collections.abc.AsyncGeneratorاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.تغییر یافته در نسخهی 3.13: پارامتر
SendTypeاکنون یک مقدار پیشفرض دارد.
- class typing.AsyncIterable(Generic[T_co])¶
نام مستعار منسوخ برای
collections.abc.AsyncIterable.اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.9:
collections.abc.AsyncIterableاکنون از اندیسدهی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.AsyncIterator(AsyncIterable[T_co])¶
نام مستعار منسوخ برای
collections.abc.AsyncIterator.اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.9:
collections.abc.AsyncIteratorاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Awaitable(Generic[T_co])¶
نام مستعار منسوخشده برای
collections.abc.Awaitable.اضافه شده در نسخهی 3.5.2.
منسوخ شده از نسخهی 3.9:
collections.abc.Awaitableاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
نامهای مستعار برای سایر ABCها در collections.abc¶
- class typing.Iterable(Generic[T_co])¶
نام مستعار منسوخشده برای
collections.abc.Iterable.منسوخ شده از نسخهی 3.9:
collections.abc.Iterableاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Iterator(Iterable[T_co])¶
نام مستعار منسوخ برای
collections.abc.Iterator.منسوخ شده از نسخهی 3.9:
collections.abc.Iteratorاکنون از زیرنویسدهی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- typing.Callable¶
نام مستعار منسوخ برای
collections.abc.Callable.برای جزئیات دربارهی نحوهی استفاده از
collections.abc.Callableوtyping.Callableدر حاشیهنویسیهای نوع، حاشیهنویسی اشیاء فراخوانیپذیر را ببینید.منسوخ شده از نسخهی 3.9:
collections.abc.Callableاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.تغییر یافته در نسخهی 3.10: اکنون
CallableازParamSpecوConcatenateپشتیبانی میکند. برای جزئیات بیشتر PEP 612 را ببینید.
- class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])¶
نام مستعار منسوخ برای
collections.abc.Generator.برای جزئیات درباره استفاده از
collections.abc.Generatorوtyping.Generatorدر حاشیهنویسیهای نوع، حاشیهنویسی تولیدگرها و همروالها را ببینید.منسوخ شده از نسخهی 3.9:
collections.abc.Generatorاکنون از زیرنویسی ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.تغییر یافته در نسخهی 3.13: مقادیر پیشفرض برای نوعهای ارسال و بازگشت افزوده شدند.
- class typing.Hashable¶
نام مستعار منسوخ برای
collections.abc.Hashable.منسوخ شده از نسخهی 3.12: در عوض، مستقیماً از
collections.abc.Hashableاستفاده کنید.
- class typing.Reversible(Iterable[T_co])¶
نام مستعار از رده خارجشده برای
collections.abc.Reversible.منسوخ شده از نسخهی 3.9:
collections.abc.Reversibleاکنون از اندیسگذاری ([]) پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.
- class typing.Sized¶
نام مستعار منسوخ برای
collections.abc.Sized.منسوخ شده از نسخهی 3.12: بهجای آن، مستقیماً از
collections.abc.Sizedاستفاده کنید.
نامهای مستعار برای کلاسهای پایه انتزاعی (ABC) در contextlib¶
- class typing.ContextManager(Generic[T_co, ExitT_co])¶
نام مستعار منسوخشده برای
contextlib.AbstractContextManager.نخستین پارامتر نوع،
T_co، نشاندهندهی نوع برگرداندهشده توسط متد__enter__()است. دومین پارامتر نوع اختیاری،ExitT_co، که بهطور پیشفرضbool | Noneاست، نشاندهندهی نوع برگرداندهشده توسط متد__exit__()است.اضافه شده در نسخهی 3.5.4.
منسوخ شده از نسخهی 3.9:
contextlib.AbstractContextManagerاکنون از زیرنویسی با[]پشتیبانی میکند. PEP 585 و Generic Alias Type را ببینید.تغییر یافته در نسخهی 3.13: دومین پارامتر نوع اختیاری،
ExitT_co، افزوده شد.
- class typing.AsyncContextManager(Generic[T_co, AExitT_co])¶
نام مستعار منسوخشده برای
contextlib.AbstractAsyncContextManager.نخستین پارامتر نوع،
T_co، نوعی را نشان میدهد که توسط متد__aenter__()بازگردانده میشود. دومین پارامتر نوع اختیاری،AExitT_co، که پیشفرض آنbool | Noneاست، نوعی را نشان میدهد که توسط متد__aexit__()بازگردانده میشود.اضافه شده در نسخهی 3.6.2.
منسوخ شده از نسخهی 3.9:
contextlib.AbstractAsyncContextManagerاکنون از زیرنویسگذاری ([]) پشتیبانی میکند. به PEP 585 و Generic Alias Type مراجعه کنید.تغییر یافته در نسخهی 3.13: پارامتر نوع اختیاری دوم،
AExitT_co، افزوده شد.
خط زمانی از رده خارج شدن ویژگیهای اصلی¶
برخی از قابلیتهای typing منسوخ شدهاند و ممکن است در نسخهای آینده از پایتون حذف شوند. جدول زیر برای راحتی شما، مهمترین موارد منسوخ را خلاصه میکند. این موضوع ممکن است تغییر کند و همهی موارد منسوخ فهرست نشدهاند.
قابلیت |
منسوخ در |
حذف پیشبینیشده |
PEP/مسئله |
|---|---|---|---|
نسخههای |
3.9 |
تعییننشده (برای اطلاعات بیشتر نامهای مستعار منسوخ را ببینید) |
|
3.9 |
3.17 |
||
3.11 |
تصمیمگرفتهنشده |
||
3.12 |
تصمیمگرفتهنشده |
||
3.12 |
تصمیمگرفتهنشده |
||
3.13 |
3.15 |
||
3.13 |
3.18 |