typing — Stöd för typtips¶
Tillagd i version 3.5.
Källkod: Lib/typing.py
Anteckning
Pythons runtime tvingar inte fram funktions- och variabeltypsannoteringar. De kan användas av tredjepartsverktyg som typkontroll, IDE:er, linters, etc.
Denna modul ger runtime-stöd för typtips.
Tänk på funktionen nedan:
def surface_area_of_cube(edge_length: float) -> str:
return f"The surface area of the cube is {6 * edge_length ** 2}."
Funktionen surface_area_of_cube tar ett argument som förväntas vara en instans av float, vilket indikeras av type hint edge_length: float. Funktionen förväntas returnera en instans av str, vilket indikeras av \-> str hintet.
Även om typhänvisningar kan vara enkla klasser som float eller str, kan de också vara mer komplexa. Modulen typing tillhandahåller en vokabulär med mer avancerade typhänvisningar.
Nya funktioner läggs ofta till i modulen typing. Paketet typing_extensions tillhandahåller bakåtporter av dessa nya funktioner till äldre versioner av Python.
Se även
- Typing cheat sheet
En snabb översikt över typtips (värd på mypy-dokumenten)
- Type System Reference-avsnittet av the mypy docs
Pythons typsystem är standardiserat via PEPs, så denna referens bör i stort sett gälla för de flesta Python-typkontrollörer. (Vissa delar kan fortfarande vara specifika för mypy.)
- Static Typing with Python
Typkontrollagnostisk dokumentation skriven av gemenskapen som beskriver typsystemets funktioner, användbara typrelaterade verktyg och bästa praxis för typning.
Specifikation för Pythons typsystem¶
Den kanoniska, uppdaterade specifikationen för Pythons typsystem finns på Specification for the Python type system.
Typ av alias¶
Ett typalias definieras med hjälp av type-satsen, som skapar en instans av TypeAliasType. I det här exemplet kommer Vector och list[float] att behandlas likvärdigt av statiska typkontrollanter:
typ Vektor = lista[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [skalär * num för num i vektor]
# klarar typkontroll; en lista med flottörer kvalificerar sig som en vektor.
ny_vektor = skala(2,0, [1,0, -4,2, 5,4])
Typaliaser är användbara för att förenkla komplexa typsignaturer. Till exempel:
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:
...
Satsen type är ny i Python 3.12. För bakåtkompatibilitet kan typaliaser också skapas genom enkel tilldelning:
Vektor = lista[float]
Eller markerad med TypeAlias för att göra det tydligt att detta är ett typalias, inte en normal variabeltilldelning:
from typing import TypeAlias
Vector: TypeAlias = list[float]
NyTyp¶
Använd hjälpen NewType för att skapa distinkta typer:
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
Den statiska typkontrollen behandlar den nya typen som om den vore en subklass av den ursprungliga typen. Detta är användbart för att hjälpa till att fånga logiska fel:
def get_user_name(user_id: UserId) -> str:
...
# passerar typkontroll
user_a = get_user_name(UserId(42351))
# misslyckas med typkontroll; en int är inte en UserId
user_b = get_user_name(-1)
Du kan fortfarande utföra alla int-operationer på en variabel av typen UserId, men resultatet kommer alltid att vara av typen int. Detta gör att du kan skicka in ett UserId överallt där ett int kan förväntas, men förhindrar att du av misstag skapar ett UserId på ett ogiltigt sätt:
# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)
Observera att dessa kontroller endast verkställs av den statiska typkontrollen. Vid körning kommer uttalandet Derived = NewType('Derived', Base) att göra Derived till en callable som omedelbart returnerar vilken parameter du än ger den. Det betyder att uttrycket Derived(some_value) inte skapar en ny klass eller introducerar mycket overhead utöver det som ett vanligt funktionsanrop gör.
Mer exakt är uttrycket något_värde är Derived(något_värde) alltid sant vid körning.
Det är ogiltigt att skapa en subtyp av Derived:
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not pass type checking
class AdminUserId(UserId): pass
Det är dock möjligt att skapa en NewType baserad på en ’härledd’ NewType:
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
och typkontroll för ProUserId kommer att fungera som förväntat.
Se PEP 484 för mer information.
Anteckning
Kom ihåg att användningen av ett typalias förklarar att två typer är ekvivalenta med varandra. Genom att göra typ Alias = Original kommer den statiska typkontrollen att behandla Alias som exakt likvärdig med Original i alla fall. Detta är användbart när du vill förenkla komplexa typsignaturer.
Däremot förklarar NewType att en typ är en subtyp av en annan. Om du gör Derived = NewType('Derived', Original) kommer den statiska typkontrollen att behandla Derived som en subklass av Original, vilket innebär att ett värde av typen Original inte kan användas på platser där ett värde av typen Derived förväntas. Detta är användbart när du vill förhindra logiska fel med minimal körtidskostnad.
Tillagd i version 3.5.2.
Ändrad i version 3.10: NewType är nu en klass snarare än en funktion. Som ett resultat av detta finns det en viss extra körtidskostnad när man anropar NewType över en vanlig funktion.
Ändrad i version 3.11: Prestandan för att anropa NewType har återställts till samma nivå som i Python 3.9.
Annotering av anropsbara objekt¶
Funktioner – eller andra callable-objekt – kan annoteras med collections.abc.Callable eller den föråldrade typing.Callable. Callable[[int], str] betecknar en funktion som tar en enda parameter av typen int och returnerar en str.
Till exempel:
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
Subscriptionsyntaxen måste alltid användas med exakt två värden: argumentlistan och returtypen. Argumentlistan måste vara en lista med typer, en ParamSpec, Concatenate eller en ellips. Returtypen måste vara en enda typ.
Om en bokstavlig ellips ... anges som argumentlista, indikerar det att en callable med godtycklig parameterlista skulle vara acceptabel:
def concat(x: str, y: str) -> str:
return x + y
x: Callable[..., str]
x = str # OK
x = concat # Also OK
Callable kan inte uttrycka komplexa signaturer som funktioner som tar ett variabelt antal argument, overloaded functions, eller funktioner som har parametrar som endast innehåller nyckelord. Dessa signaturer kan dock uttryckas genom att definiera en Protocol -klass med en __call__()-metod:
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
Anropsbara filer som tar andra anropsbara filer som argument kan ange att deras parametertyper är beroende av varandra med hjälp av ParamSpec. Dessutom, om denna anropsbarhet lägger till eller tar bort argument från andra anropsbara objekt, kan operatorn Concatenate användas. De har formen Callable[ParamSpecVariable, ReturnType] respektive Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType].
Ändrad i version 3.10: Callable stöder nu ParamSpec och Concatenate. Se PEP 612 för mer information.
Se även
Dokumentationen för ParamSpec och Concatenate ger exempel på användning i Callable.
Generiska läkemedel¶
Eftersom typinformation om objekt som förvaras i containrar inte kan härledas statiskt på ett generiskt sätt, stöder många containerklasser i standardbiblioteket subscription för att ange de förväntade typerna av containerelement.
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: ...
Generiska funktioner och klasser kan parametriseras med hjälp av type parameter syntax:
from collections.abc import Sequence
def first[T](l: Sequence[T]) -> T: # Function is generic over the TypeVar "T"
return l[0]
Eller genom att använda TypeVar-fabriken direkt:
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]
Ändrad i version 3.12: Syntaktiskt stöd för generics är nytt i Python 3.12.
Annotering av tuples¶
För de flesta behållare i Python förutsätter typningssystemet att alla element i behållaren är av samma typ. Till exempel:
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 accepterar bara ett typargument, så en typkontroll skulle ge ett felmeddelande om y-tilldelningen ovan. På samma sätt accepterar Mapping bara två typargument: det första anger typen av nycklar och det andra anger typen av värden.
Till skillnad från de flesta andra Python-containrar är det dock vanligt i idiomatisk Python-kod att tupler har element som inte alla är av samma typ. Av denna anledning är tupler specialklassade i Pythons typsystem. tuple accepterar valfritt antal typargument:
# 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)
För att beteckna en tupel som kan vara av valfri längd och där alla element är av samma typ T, använd tuple[T, ...]. För att beteckna en tom tupel, använd tuple[()]. Att använda vanlig tuple som en annotation är likvärdigt med att använda 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 = ()
Typ av klassobjekt¶
En variabel annoterad med C kan acceptera ett värde av typen C. Däremot kan en variabel annoterad med type[C] (eller föråldrade typing.Type[C]) acceptera värden som är klasser i sig – specifikt kommer den att acceptera class object av C. Till exempel:
a = 3 # Har typen ``int``
b = int # Har typen ``typ[int]``
c = type(a) # Har också typen ``type[int]``
Observera att type[C] är kovariant:
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]``
De enda lagliga parametrarna för type är klasser, Any, type variables och unioner av någon av dessa typer. Till exempel:
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] är ekvivalent med type, som är roten till Pythons metaklasshierarki.
Annotering av generatorer och coroutines¶
En generator kan annoteras med hjälp av den generiska typen Generator[YieldType, SendType, ReturnType]. Till exempel:
def echo_round() -> Generator[int, float, str]:
sent = yield 0
while sent >= 0:
sent = yield round(sent)
return 'Done'
Observera att till skillnad från många andra generiska klasser i standardbiblioteket beter sig SendType i Generator kontravariant, inte kovariant eller invariant.
Parametrarna SendType och ReturnType är som standard None:
def infinite_stream(start: int) -> Generator[int]:
while True:
yield start
start += 1
Det är också möjligt att ange dessa typer explicit:
def infinite_stream(start: int) -> Generator[int, None, None]:
while True:
yield start
start += 1
Enkla generatorer som bara ger värden kan också annoteras som att de har en returtyp av antingen Iterable[YieldType] eller Iterator[YieldType]:
def infinite_stream(start: int) -> Iterator[int]:
while True:
yield start
start += 1
Asynkrona generatorer hanteras på ett liknande sätt, men förvänta dig inte ett argument av typen ReturnType (AsyncGenerator[YieldType, SendType]). Argumentet SendType är som standard None, så följande definitioner är likvärdiga:
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)
Precis som i det synkrona fallet är AsyncIterable[YieldType] och AsyncIterator[YieldType] också tillgängliga:
async def infinite_stream(start: int) -> AsyncIterator[int]:
while True:
yield start
start = await increment(start)
Coroutines kan annoteras med Coroutine[YieldType, SendType, ReturnType]. Generiska argument motsvarar de i Generator, till exempel:
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
Användardefinierade generiska typer¶
En användardefinierad klass kan definieras som en generisk klass.
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)
Denna syntax indikerar att klassen LoggedVar är parametriserad kring en enda typvariabel T . Detta gör också att T är giltigt som typ inom klassens kropp.
Generiska klasser ärver implicit från Generic. För kompatibilitet med Python 3.11 och lägre är det också möjligt att ärva explicit från Generic för att ange en generisk klass:
from typing import TypeVar, Generic
T = TypeVar('T')
class LoggedVar(Generic[T]):
...
Generiska klasser har __class_getitem__()-metoder, vilket innebär att de kan parametriseras vid körning (t.ex. LoggedVar[int] nedan):
from collections.abc import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
En generisk typ kan ha ett valfritt antal typvariabler. Alla varianter av TypeVar är tillåtna som parametrar för en generisk typ:
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]):
...
Varje typvariabelargument till Generic måste vara distinkt. Detta är alltså ogiltigt:
from typing import TypeVar, Generic
...
class Pair[M, M]: # SyntaxError
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
Generiska klasser kan också ärva från andra klasser:
from collections.abc import Sized
class LinkedList[T](Sized):
...
När man ärvde från generiska klasser kunde vissa typparametrar fixas:
from collections.abc import Mapping
class MyDict[T](Mapping[str, T]):
...
I det här fallet har MyDict en enda parameter, T.
Om man använder en generisk klass utan att ange typparametrar antas Any för varje position. I följande exempel är MyIterable inte generisk utan ärver implicit från Iterable[Any]:
from collections.abc import Iterable
class MyIterable(Iterable): # Same as Iterable[Any]
...
Användardefinierade alias för generiska typer stöds också. Exempel:
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)
För bakåtkompatibilitet kan generiska typaliaser också skapas genom en enkel tilldelning:
from collections.abc import Iterable
from typing import TypeVar
S = TypeVar("S")
Response = Iterable[S] | int
Ändrad i version 3.7: Generic har inte längre någon egen metaklass.
Ändrad i version 3.12: Syntaktiskt stöd för generiska klasser och typalias är nytt i version 3.12. Tidigare var generiska klasser tvungna att uttryckligen ärva från Generic eller innehålla en typvariabel i en av sina baser.
Användardefinierad generik för parameteruttryck stöds också via parameterspecifikationsvariabler i formen [**P]. Beteendet överensstämmer med typvariabler som beskrivs ovan eftersom parameterspecifikationsvariabler behandlas av modulen typing som en specialiserad typvariabel. Det enda undantaget från detta är att en lista med typer kan användas för att ersätta en ParamSpec:
>>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec
...
>>> Z[int, [dict, float]]
__main__.Z[int, [dict, float]]
Klasser som är generiska över en ParamSpec kan också skapas med hjälp av explicit arv från Generic. I detta fall används inte **:
from typing import ParamSpec, Generic
P = ParamSpec('P')
class Z(Generic[P]):
...
En annan skillnad mellan TypeVar och ParamSpec är att en generik med endast en parameterspecifikationsvariabel kommer att acceptera parameterlistor i formerna X[[Type1, Type2, ...]] och även X[Type1, Type2, ...] av estetiska skäl. Internt konverteras den senare till den förra, så följande är likvärdiga:
>>> class X[**P]: ...
...
>>> X[int, str]
__main__.X[[int, str]]
>>> X[[int, str]]
__main__.X[[int, str]]
Observera att generiker med ParamSpec kanske inte har korrekta __parametrar__ efter substitution i vissa fall eftersom de främst är avsedda för statisk typkontroll.
Ändrad i version 3.10: Generic kan nu parametriseras över parameteruttryck. Se ParamSpec och PEP 612 för mer information.
En användardefinierad generisk klass kan ha ABC som basklasser utan att det uppstår en metaklasskonflikt. Generiska metaklasser stöds inte. Resultatet av parametrisering av generiska klasser cachas och de flesta typer i modulen typing är hashable och jämförbara med avseende på likhet.
Typen Any¶
En speciell typ av typ är Any. En statisk typkontroll kommer att behandla varje typ som kompatibel med Any och Any som kompatibel med varje typ.
Detta innebär att det är möjligt att utföra valfri operation eller metodanrop på ett värde av typen Any och tilldela det till valfri variabel:
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()
...
Observera att ingen typkontroll utförs när ett värde av typen Any tilldelas till en mer exakt typ. Till exempel rapporterade den statiska typkontrollen inte ett fel när a tilldelades s trots att s deklarerades vara av typen str och får ett värde av typen int vid körning!
Dessutom kommer alla funktioner utan returtyp eller parametertyper att implicit använda Any:
def legacy_parser(text):
...
returnera data
# En statisk typkontroll kommer att behandla ovanstående
# som att den har samma signatur som:
def legacy_parser(text: Any) -> Any:
...
returnerar data
Detta beteende gör att Any kan användas som en escape-lucka när du behöver blanda dynamiskt och statiskt typad kod.
Kontrastera beteendet hos Any med beteendet hos object. I likhet med Any är varje typ en subtyp av object. Men till skillnad från Any är det omvända inte sant: object är inte en subtyp av alla andra typer.
Det innebär att när typen av ett värde är object, kommer en typkontroll att avvisa nästan alla operationer på det, och att tilldela det till en variabel (eller använda det som ett returvärde) av en mer specialiserad typ är ett typfel. Till exempel:
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 compatible with all types
hash_b(42)
hash_b("foo")
Använd object för att ange att ett värde kan vara av vilken typ som helst på ett typsäkert sätt. Använd Any för att ange att ett värde är dynamiskt typat.
Nominell kontra strukturell subtypning¶
Ursprungligen definierade PEP 484 Pythons statiska typsystem som att det använder nominal subtyping. Detta innebär att en klass A är tillåten där en klass B förväntas om och endast om A är en subklass av B.
Detta krav gällde tidigare även för abstrakta basklasser, såsom Iterable. Problemet med detta tillvägagångssätt är att en klass måste markeras explicit för att stödja dem, vilket är opytoniskt och olikt vad man normalt skulle göra i idiomatisk dynamiskt typad Python-kod. Till exempel överensstämmer detta med 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 löser detta problem genom att tillåta användare att skriva ovanstående kod utan explicita basklasser i klassdefinitionen, vilket gör att Bucket implicit kan betraktas som en subtyp av både Sized och Iterable[int] av statiska typkontroller. Detta är känt som strukturell subtypning (eller statisk duck-typning):
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
Genom att subklassa en speciell klass Protocol kan en användare dessutom definiera nya anpassade protokoll för att fullt ut utnyttja strukturell subtypning (se exempel nedan).
Modulens innehåll¶
Modulen typing definierar följande klasser, funktioner och dekoratorer.
Särskilda typningsprimitiver¶
Särskilda typer¶
Dessa kan användas som typer i annoteringar. De stöder inte prenumeration med hjälp av [].
- typing.Any¶
Särskild typ som anger en obegränsad typ.
Ändrad i version 3.11:
Anykan nu användas som basklass. Detta kan vara användbart för att undvika fel i typkontrollerna för klasser som kan få typ var som helst eller som är mycket dynamiska.
- typing.AnyStr¶
-
Definition:
AnyStr = TypeVar('AnyStr', str, bytes)
AnySträr avsedd att användas för funktioner som kan accepterastrellerbytesargument men som inte kan tillåta att de två blandas.Till exempel:
def concat(a: AnyStr, b: AnyStr) -> AnyStr: returnerar a + b concat("foo", "bar") # OK, utdata har typen 'str' concat(b"foo", b"bar") # OK, utdata har typen 'bytes' concat("foo", b"bar") # Fel, kan inte blanda str och bytes
Observera att trots sitt namn har
AnyStringet att göra med typenAny`och betyder inte heller ”vilken sträng som helst”. I synnerhet skiljer sigAnyStrochstr | bytesfrån varandra och har olika användningsområden:# Ogiltig användning av AnyStr: # Typvariabeln används bara en gång i funktionssignaturen, # så den kan inte "lösas" av typkontrollen def greet_bad(cond: bool) -> AnyStr: return "hej där!" if cond else b"hälsningar!" # Det bättre sättet att kommentera den här funktionen: def greet_proper(cond: bool) -> str | bytes: return "hej där!" if cond else b"hälsningar!"
Deprecated since version 3.13, will be removed in version 3.18: Föråldrad till förmån för den nya typ parametersyntaxen. Använd
class A[T: (str, bytes)]: ...istället för att importeraAnyStr. Se PEP 695 för mer information.I Python 3.16 kommer
AnyStratt tas bort fråntyping.__all__, och deprecation-varningar kommer att utfärdas vid körning när den nås eller importeras fråntyping.AnyStrkommer att tas bort fråntypingi Python 3.18.
- typing.LiteralString¶
Speciell typ som endast innehåller bokstavliga strängar.
Alla bokstavliga strängar är kompatibla med
LiteralString, liksom en annanLiteralString. Men ett objekt typat som barasträr inte det. En sträng som skapas genom att komponeraLiteralString-typade objekt är också acceptabel som enLiteralString.Exempel:
def run_query(sql: LiteralString) -> Ingen: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: run_query("SELECT * FROM studenter") # OK run_query(litteral_sträng) # OK run_query("SELECT * FROM " + literal_string) # OK run_query(godtycklig_sträng) # typkontrollfel run_query( # typkontrollfel f"SELECT * FROM studenter WHERE namn = {arbitrary_string}" )
LiteralStringär användbart för känsliga API:er där godtyckliga användargenererade strängar kan skapa problem. Till exempel kan de två fallen ovan som genererar typkontrollfel vara sårbara för en SQL-injektionsattack.Se PEP 675 för mer information.
Tillagd i version 3.11.
- typing.Never¶
- typing.NoReturn¶
NeverochNoReturnrepresenterar bottentypen, en typ som inte har några medlemmar.De kan användas för att ange att en funktion aldrig återkommer, t.ex.
sys.exit():from typing import Never # or NoReturn def stop() -> Never: raise RuntimeError('no way')
Eller för att definiera en funktion som aldrig ska anropas, eftersom det inte finns några giltiga argument, t.ex.
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)
NeverochNoReturnhar samma betydelse i typsystemet och statiska typkontroller behandlar båda likvärdigt.Tillagd i version 3.6.2: Lagt till
NoReturn.Tillagd i version 3.11: Lagt till
Never.
- typing.Self¶
Speciell typ för att representera den aktuella inneslutna klassen.
Till exempel:
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"
Denna annotation är semantiskt likvärdig med följande, om än på ett mer kortfattat sätt:
from typing import TypeVar Self = TypeVar("Self", bound="Foo") class Foo: def return_self(self: Self) -> Self: ... return self
I allmänhet, om något returnerar
self, som i exemplen ovan, bör du användaSelfsom returannotering. OmFoo.return_selfannoterades som att returnera"Foo", skulle typkontrollen härleda objektet som returneras frånSubclassOfFoo.return_selfsom att vara av typenFoosnarare änSubclassOfFoo.Andra vanliga användningsområden är t.ex:
classmethodsom används som alternativa konstruktörer och returnerar instanser av parameterncls.Anteckna en
__enter__()-metod som returnerar self.
Du bör inte använda
Selfsom returannotering om metoden inte garanterat returnerar en instans av en underklass när klassen är underklassad: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()
Se PEP 673 för mer information.
Tillagd i version 3.11.
- typing.TypeAlias¶
Särskild annotering för att explicit deklarera en typ alias.
Till exempel:
from typing import TypeAlias Factors: TypeAlias = list[int]
TypeAliasär särskilt användbart på äldre Python-versioner för att annotera alias som använder sig av framåtriktade referenser, eftersom det kan vara svårt för typkontrollanter att skilja dessa från normala variabeltilldelningar: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: ...
Se PEP 613 för mer information.
Tillagd i version 3.10.
Föråldrad sedan version 3.12:
TypeAliasär avfört till förmån förtype-satsen, som skapar instanser avTypeAliasTypeoch som stöder framåtriktade referenser. Observera att även omTypeAliasochTypeAliasTypetjänar liknande syften och har liknande namn, är de distinkta och den senare är inte typen av den förra. Avlägsnande avTypeAliasär för närvarande inte planerat, men användare uppmuntras att migrera tilltype-satser.
Särskilda formulär¶
Dessa kan användas som typer i annoteringar. De stöder alla prenumeration med hjälp av [], men varje har en unik syntax.
- class typing.Union¶
Unionstyp;
Union[X, Y]är ekvivalent medX | Yoch betyder antingen X eller Y.För att definiera en union, använd t.ex.
Union[int, str]eller kortformenint | str. Det är rekommenderat att använda den kortformen. Mer information:Argumenten måste vara typer och det måste finnas minst ett.
Unioner av unioner är tillplattade, t.ex.:
Union[Union[int, str], float] == Union[int, str, float]
Detta gäller dock inte för unioner som refereras till via ett typalias, för att undvika att tvinga fram en utvärdering av den underliggande
TypeAliasType:typ A = Union[int, str] Union[A, float] != Union[int, str, float]
Sammanslutningar av ett enda argument försvinner, t.ex.:
Union[int] == int # Konstruktören returnerar faktiskt int
Överflödiga argument hoppas över, t.ex.:
Union[int, str, int] == Union[int, str] == int | str
Vid jämförelse av unioner ignoreras argumentordningen, t.ex.:
Union[int, str] == Union[str, int]
Du kan inte underklassa eller instansiera en
Union.Du kan inte skriva
Union[X][Y].
Ändrad i version 3.7: Ta inte bort explicita underklasser från unioner vid körning.
Ändrad i version 3.10: Unioner kan nu skrivas som
X | Y. Se unionstyputtryck.Ändrad i version 3.14:
types.UnionTypeär nu ett alias förUnion, och bådeUnion[int, str]ochint | strskapar instanser av samma klass. För att kontrollera om ett objekt är enUnionvid runtime, användisinstance(obj, Union). För kompatibilitet med tidigare versioner av Python, användget_origin(obj) is typing.Union or get_origin(obj) is types.UnionType.
- typing.Optional¶
Optional[X]är ekvivalent medX | None(ellerUnion[X, None]).Observera att detta inte är samma koncept som ett optionellt argument, vilket är ett argument som har en default. Ett valfritt argument med en standard kräver inte
Optionalkvalifieraren på sin typannotering bara för att det är valfritt. Till exempel:def foo(arg: int = 0) -> None: ...
Å andra sidan, om ett explicit värde av
Noneär tillåtet, är användningen avOptionallämplig, oavsett om argumentet är valfritt eller inte. Till exempel:def foo(arg: Valfritt[int] = Ingen) -> Ingen: ...
Ändrad i version 3.10: Optional kan nu skrivas som
X | None. Se unionstyputtryck.
- typing.Concatenate¶
Särskilt formulär för annotering av funktioner av högre ordning.
Concatenatekan användas tillsammans med Callable ochParamSpecför att kommentera en högre ordningens anropbar som lägger till, tar bort eller omvandlar parametrar i en annan anropbar. Användningen är i form avConcatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable].Concatenateär för närvarande endast giltigt när det används som det första argumentet till en Callable. Den sista parametern tillConcatenatemåste vara enParamSpeceller ellips (...).Till exempel, för att annotera en dekorator
with_locksom tillhandahåller enthreading.Locktill den dekorerade funktionen, kanConcatenateanvändas för att indikera attwith_lockförväntar sig en anropbar som tar in enLocksom första argument, och returnerar en anropbar med en annan typsignatur. I detta fall indikerarParamSpecatt parametertyperna för den returnerade anropbara är beroende av parametertyperna för den anropbara som skickas in: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]: '''A type-safe decorator which provides a lock.''' 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: '''Add a list of numbers together in a thread-safe manner.''' 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])
Tillagd i version 3.10.
Se även
PEP 612 – Variabler för parameterspecifikation (PEP:n som introducerade
ParamSpecochConcatenate)
- typing.Literal¶
Särskild typform för att definiera ”bokstavstyper”.
Literalkan användas för att indikera för typkontrollanter att det annoterade objektet har ett värde som motsvarar en av de angivna litteralerna.Till exempel:
def validate_simple(data: Any) -> Literal[True]: # returnerar alltid True ... type Mode = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: Mode) -> str: ... open_helper('/some/path', 'r') # Klarar typkontroll open_helper('/other/path', 'typo') # Fel i typkontrollen
Literal[...]kan inte underklassas. Vid körning tillåts ett godtyckligt värde som typargument tillLiteral[...], men typkontrollanter kan införa restriktioner. Se PEP 586 för mer information om litterala typer.Ytterligare detaljer:
Argumenten måste vara bokstavliga värden och det måste finnas minst ett.
Nästlade
Literal-typer plattas ut, t.ex.:assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]
Detta gäller dock inte för
Literal-typer som refereras till via ett typalias, för att undvika att tvinga fram en utvärdering av den underliggandeTypeAliasType:typ A = Litteral[1, 2] assert Litteral[A, 3] != Litteral[1, 2, 3]
Överflödiga argument hoppas över, t.ex.:
assert Literal[1, 2, 1] == Literal[1, 2]
Vid jämförelse av literaler ignoreras argumentordningen, t.ex.:
assert Literal[1, 2] == Literal[2, 1]
Du kan inte underklassa eller instansiera en
Literal.Du kan inte skriva
Literal[X][Y].
Tillagd i version 3.8.
- typing.ClassVar¶
Särskild typkonstruktion för att markera klassvariabler.
Som introducerades i PEP 526, anger en variabelannotation omsluten av ClassVar att ett visst attribut är avsett att användas som en klassvariabel och inte bör ställas in på instanser av den klassen. Användning:
class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable
ClassVaraccepterar endast typer och kan inte tecknas ytterligare.ClassVarär inte en klass i sig, och bör inte användas medisinstance()ellerissubclass().ClassVarändrar inte Pythons körtidsbeteende, men kan användas av tredjeparts typkontrollanter. Till exempel kan en typkontrollant flagga följande kod som ett fel:enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OK
Tillagd i version 3.5.3.
- typing.Final¶
Särskild typkonstruktion för att ange slutliga namn till typkontrollanter.
Slutnamn kan inte omfördelas i något scope. Slutnamn som deklareras i klassens scope kan inte åsidosättas i underklasser.
Till exempel:
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
Det finns ingen körtidskontroll av dessa egenskaper. Se PEP 591 för mer information.
Tillagd i version 3.8.
- typing.Required¶
Speciell typningskonstruktion för att markera en
TypedDict-nyckel som nödvändig.Detta är främst användbart för
total=FalseTypedDicts. SeTypedDictoch PEP 655 för mer information.Tillagd i version 3.11.
- typing.NotRequired¶
Speciell typningskonstruktion för att markera en
TypedDict-nyckel som potentiellt saknad.Se
TypedDictoch PEP 655 för mer information.Tillagd i version 3.11.
- typing.ReadOnly¶
En speciell typningskonstruktion för att markera ett objekt i en
TypedDictsom skrivskyddat.Till exempel:
class Movie(TypedDict): title: ReadOnly[str] year: int def mutate_movie(m: Movie) -> None: m["year"] = 1999 # allowed m["title"] = "The Matrix" # typechecker error
Det finns ingen runtime-kontroll för denna egenskap.
Se
TypedDictoch PEP 705 för mer information.Tillagd i version 3.13.
- typing.Annotated¶
Särskilt skrivformulär för att lägga till kontextspecifika metadata i en annotering.
Lägg till metadata
xtill en given typTgenom att använda annotationenAnnotated[T, x]. Metadata som läggs till medAnnotatedkan användas av statiska analysverktyg eller vid körning. Vid körning lagras metadata i ett__metadata__-attribut.Om ett bibliotek eller verktyg stöter på en annotation
Annotated[T, x]och inte har någon speciell logik för metadata, bör det ignorera metadata och helt enkelt behandla annotationen somT. Som sådan kanAnnotatedvara användbar för kod som vill använda annotationer för ändamål utanför Pythons statiska typningssystem.Att använda
Annotated[T, x]som en annotation tillåter fortfarande statisk typkontroll avT, eftersom typkontrollerna helt enkelt ignorerar metadatax. På så sätt skiljer sigAnnotatedfrån dekoratorn@no_type_check, som också kan användas för att lägga till annotationer utanför typsystemets räckvidd, men som helt inaktiverar typkontroll för en funktion eller klass.Ansvaret för hur metadata ska tolkas ligger hos det verktyg eller bibliotek som stöter på en
Annotated-annotation. Ett verktyg eller bibliotek som stöter på enAnnotated-typ kan söka igenom metadataelementen för att avgöra om de är av intresse (t.ex. med hjälp avisinstance()).- Annotated[<type>, <metadata>]
Här är ett exempel på hur du kan använda
Annotatedför att lägga till metadata till typannoteringar om du gör intervallanalys:@dataclass class ValueRange: lo: int hi: int T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)]
Det första argumentet till
Annotatedmåste vara en giltig typ. Flera metadataelement kan anges eftersomAnnotatedstöder variadiska argument. Ordningen på metadataelementen bevaras och är viktig för jämlikhetskontroller:@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
Det är upp till det verktyg som konsumerar annotationerna att avgöra om klienten får lägga till flera metadataelement i en annotation och hur dessa annotationer ska slås samman.
Nästlade
Annotated-typer plattas ut. Ordningen på metadataelementen börjar med den innersta annotationen:assert Annoterad[Annoterad[int, ValueRange(3, 10)], ctype("char")] == Annoterad[ int, Värdeintervall(3, 10), ctype("char") ]
Detta gäller dock inte för
Annoteradetyper som refereras till via ett typalias, för att undvika att tvinga fram en utvärdering av den underliggandeTypeAliasType:type From3To10[T] = Annoterad[T, ValueRange(3, 10)] assert Annoterad[From3To10[int], ctype("char")] != Annoterad[ int, Värdeintervall(3, 10), ctype("char") ]
Duplicerade metadataelement tas inte bort:
assert Annoterad[int, Värdeintervall(3, 10)] != Annoterad[ int, Värdeintervall(3, 10), Värdeintervall(3, 10) ]
Annotatedkan användas med nästlade och generiska alias:@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]
Annotatedkan inte användas med en uppackadTypeVarTuple:type Variadic[*Ts] = Annoterad[*Ts, Ann1] = Annoterad[T1, T2, T3, ..., Ann1] # INTE giltig
där
T1,T2, … ärTypeVars. Detta är ogiltigt eftersom endast en typ ska skickas till Annotated.Som standard tar
get_type_hints()bort metadata från annoteringar. Passerainclude_extras=Trueför att få metadata bevarade:>>> 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'>}
Vid körning kan de metadata som är associerade med en
Annotated-typ hämtas via attributet__metadata__:>>> from typing import Annotated >>> X = Annotated[int, "very", "important", "metadata"] >>> X typing.Annotated[int, 'very', 'important', 'metadata'] >>> X.__metadata__ ('very', 'important', 'metadata')
Om du vill hämta den ursprungliga typen som omsluts av
Annotated, använd attributet__origin__`:>>> from typing import Annotated, get_origin >>> Password = Annotated[str, "secret"] >>> Password.__origin__ <class 'str'>
Observera att om du använder
get_origin()kommerAnnotatedsjälv att returneras:>>> get_origin(Password) typing.Annotated
Se även
- PEP 593 - Flexibla funktions- och variabelannoteringar
PEP som introducerar
Annotatedtill standardbiblioteket.
Tillagd i version 3.9.
- typing.TypeIs¶
Särskild typkonstruktion för att markera användardefinierade typpredikatsfunktioner.
TypeIskan användas för att kommentera returtypen för en användardefinierad typ predikatfunktion.TypeIsaccepterar endast ett enda typargument. Vid körning ska funktioner som markeras på detta sätt returnera en boolean och ta minst ett positionellt argument.TypeIssyftar till att gynna type narrowing – en teknik som används av statiska typkontroller för att bestämma en mer exakt typ av ett uttryck inom ett programs kodflöde. Vanligtvis görs typförminskning genom att analysera villkorligt kodflöde och tillämpa förminskningen på ett kodblock. Det villkorliga uttrycket här kallas ibland för ett ”typ predikat”:def is_str(val: str | float): # "isinstance" typ predikat if isinstance(val, str): # Typen av ``val`` är begränsad till ``str`` ... else: # Annars är typen av ``val`` begränsad till ``float``. ...
Ibland kan det vara praktiskt att använda en användardefinierad boolesk funktion som ett typpredikat. En sådan funktion bör använda
TypeIs[...]ellerTypeGuardsom sin returtyp för att varna statiska typkontrollanter för denna avsikt.TypeIshar vanligtvis ett mer intuitivt beteende änTypeGuard, men det kan inte användas när in- och utdatatyperna är inkompatibla (t.ex.list[object]tilllist[int]) eller när funktionen inte returnerarTrueför alla instanser av den begränsade typen.Att använda
\-> TypeIs[NarrowedType]säger till den statiska typkontrollen att för en given funktion:Returvärdet är en boolean.
Om returvärdet är
Trueär typen för dess argument skärningspunkten mellan argumentets ursprungliga typ ochNarrowedType.Om returvärdet är
False, begränsas typen av dess argument för att uteslutaNarrowedType.
Till exempel:
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)
Typen i
TypeIsmåste stämma överens med typen i funktionens argument; om den inte gör det kommer statiska typkontroller att ge ett felmeddelande. En felaktigt skrivenTypeIs-funktion kan leda till osunt beteende i typsystemet; det är användarens ansvar att skriva sådana funktioner på ett typsäkert sätt.Om en
TypeIs-funktion är en klass- eller instansmetod, mappar typen iTypeIstill typen för den andra parametern (efterclsellerself).Kort sagt, formen
def foo(arg: TypeA) -> TypeIs[TypeB]: ..., betyder att omfoo(arg)returnerarTrue, så ärargen instans avTypeB, och om den returnerarFalse, så är den inte en instans avTypeB.TypeIsfungerar också med typvariabler. För mer information, se PEP 742 (Begränsa typer medTypeIs).Tillagd i version 3.13.
- typing.TypeGuard¶
Särskild typkonstruktion för att markera användardefinierade typpredikatsfunktioner.
Type predicate functions är användardefinierade funktioner som returnerar om deras argument är en instans av en viss typ.
TypeGuardfungerar på liknande sätt somTypeIs, men har subtilt olika effekter på typkontrollbeteendet (se nedan).Att använda
\-> TypeGuardsäger till den statiska typkontrollen att för en given funktion:Returvärdet är en boolean.
Om returvärdet är
True, är typen av dess argument den typ som finns iTypeGuard.
TypeGuardfungerar även med typvariabler. Se PEP 647 för mer information.Till exempel:
def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Bestämmer om alla objekt i listan är strängar''' return all(isinstance(x, str) för x i val) def func1(val: lista[objekt]): if is_str_list(val): # Typen av ``val`` begränsas till ``list[str]``. print(" ".join(val)) else: # Typen av ``val`` förblir ``list[object]``. print("Inte en lista med strängar!")
TypeIsochTypeGuardskiljer sig åt på följande sätt:TypeIskräver att den inskränkta typen är en subtyp av inmatningstypen, medanTypeGuardinte gör det. Huvudskälet är att tillåta saker som att begränsalist[object]tilllist[str]även om den senare inte är en subtyp av den förra, eftersomlistär invariant.När en
TypeGuard-funktion returnerarTrue, begränsar typkontrollerna variabelns typ till exaktTypeGuard-typen. När enTypeIs-funktion returnerarTruekan typkontrollanter härleda en mer exakt typ genom att kombinera den tidigare kända typen av variabeln medTypeIs-typen. (Tekniskt sett är detta känt som en intersektionstyp.)När en
TypeGuard-funktion returnerarFalsekan typkontrollanter inte begränsa variabelns typ alls. När enTypeIs-funktion returnerarFalsekan typkontrollanter begränsa variabelns typ för att uteslutaTypeIs-typen.
Tillagd i version 3.10.
- typing.Unpack¶
Typoperator för att konceptuellt markera att ett objekt har packats upp.
Om du till exempel använder uppackningsoperatorn
*på en typvariabel-tupel är det likvärdigt med att användaUnpackför att markera att typvariabel-tupeln har packats upp:Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Gör det effektivt: tup: tuple[Unpack[Ts]]
I själva verket kan
Unpackanvändas omväxlande med*i samband medtyping.TypeVarTupleochbuiltins.tupletyper. Du kan seUnpackanvändas explicit i äldre versioner av Python, där*inte kunde användas på vissa ställen:# I äldre versioner av Python finns TypeVarTuple och Unpack # finns i bakportspaketet `typing_extensions`. from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Syntaxfel på Python <= 3.10! tup: tuple[Unpack[Ts]] # Semantiskt likvärdig och bakåtkompatibel
Unpackkan också användas tillsammans medtyping.TypedDictför att skriva**kwargsi en funktionssignatur: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]): ...
Se PEP 692 för mer information om att använda
Unpackför**kwargstypning.Tillagd i version 3.11.
Skapa generiska typer och typaliaser¶
Följande klasser bör inte användas direkt som annotationer. Deras avsedda syfte är att vara byggstenar för att skapa generiska typer och typaliaser.
Dessa objekt kan skapas genom speciell syntax (typ parameterlistor och type-satsen). För kompatibilitet med Python 3.11 och tidigare kan de också skapas utan den särskilda syntaxen, enligt vad som dokumenteras nedan.
- class typing.Generic¶
Abstrakt basklass för generiska typer.
En generisk typ deklareras vanligen genom att en lista med typparametrar läggs till efter klassnamnet:
class Mapping[KT, VT]: def __getitem__(self, key: KT) -> VT: ... # Etc.
En sådan klass ärver implicit från
Generic. Körtidssemantiken för denna syntax diskuteras i Language Reference.Denna klass kan sedan användas på följande sätt:
def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mappning[nyckel] utom KeyError: returnera standard
Här anger parenteserna efter funktionsnamnet en generisk funktion.
För bakåtkompatibilitet kan generiska klasser också deklareras genom att uttryckligen ärva från
Generic. I detta fall måste typ-parametrarna deklareras separat: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)¶
Typ av variabel.
Det föredragna sättet att konstruera en typvariabel är via den särskilda syntaxen för generiska funktioner, generiska klasser och generiska typalias:
class Sequence[T]: # T is a TypeVar ...
Denna syntax kan också användas för att skapa avgränsade och begränsade typvariabler:
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 ...
Om så önskas kan återanvändbara typvariabler dock också konstrueras manuellt, på följande sätt:
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
Typvariabler är främst till för att underlätta för statiska typkontrollanter. De fungerar som parametrar för generiska typer samt för generiska funktions- och typaliasdefinitioner. Se
Genericför mer information om generiska typer. Generiska funktioner fungerar på följande sätt:def repeat[T](x: T, n: int) -> Sekvens[T]: """Returnera en lista som innehåller n referenser till x."""" returnerar [x]*n def print_capitalized[S: str](x: S) -> S: """Skriv ut x med stora bokstäver och returnera x.""" print(x.capitalize()) returnerar x def concatenate[A: (str, bytes)](x: A, y: A) -> A: """Lägg ihop två strängar eller bytes-objekt.""" returnerar x + y
Observera att typvariabler kan vara bounded, constrained eller ingetdera, men kan inte vara både bounded och constrained.
Variansen hos typvariabler härleds av typkontrollanter när de skapas genom type-parametersyntaxen eller när
infer_variance=Trueanges. Manuellt skapade typvariabler kan uttryckligen markeras som covarianta eller contravarianta genom att angecovariant=Trueellercontravariant=True. Som standard är manuellt skapade typvariabler invarianta. Se PEP 484 och PEP 695 för mer information.Variabler av typen Bounded och variabler av typen Constrained har olika semantik på flera viktiga sätt. Att använda en begränsad typvariabel innebär att
TypeVarkommer att lösas med hjälp av den mest specifika typ som är möjlig: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
Den övre gränsen för en typvariabel kan vara en konkret typ, en abstrakt typ (ABC eller Protocol) eller till och med en sammanslagning av typer:
# 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
Att använda en begränsad typvariabel innebär dock att
TypVarbara någonsin kan lösas som exakt en av de begränsningar som anges:a = konkatenera('ett', 'två') reveal_type(a) # avslöjad typ är str b = konkatenera(StringSubclass('ett'), StringSubclass('två')) reveal_type(b) # avslöjad typ är str, trots att StringSubclass skickades in c = concatenate('one', b'two') # fel: typvariabeln 'A' kan vara antingen str eller bytes i ett funktionsanrop, men inte båda
Vid körning kommer
isinstance(x, T)att ge upphov tillTypeError.- __name__¶
Namnet på typvariabeln.
- __covariant__¶
Om typen var uttryckligen har markerats som kovariant.
- __contravariant__¶
Om typen var uttryckligen har markerats som kontravariant.
- __infer_variance__¶
Huruvida typvariabelns varians ska härledas av typkontrollanter.
Tillagd i version 3.12.
- __bound__¶
Den övre gränsen för typvariabeln, om sådan finns.
Ändrad i version 3.12: För typvariabler som skapats genom typ parametersyntax utvärderas bindningen endast när attributet används, inte när typvariabeln skapas (se Ledig utvärdering).
- evaluate_bound()¶
En evaluate function som motsvarar attributet
__bound__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__bound__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format.Tillagd i version 3.14.
- __constraints__¶
En tupel som innehåller begränsningarna för typvariabeln, om sådana finns.
Ändrad i version 3.12: För typvariabler som skapats genom type parameter syntax utvärderas begränsningarna endast när attributet används, inte när typvariabeln skapas (se Ledig utvärdering).
- evaluate_constraints()¶
En evaluate function som motsvarar attributet
__constraints__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__constraints__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format.Tillagd i version 3.14.
- __default__¶
Typvariabelns standardvärde, eller
typing.NoDefaultom den inte har något standardvärde.Tillagd i version 3.13.
- evaluate_default()¶
En evaluate function som motsvarar attributet
__default__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__default__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format.Tillagd i version 3.14.
- has_default()¶
Returnerar om typvariabeln har ett standardvärde eller inte. Detta är likvärdigt med att kontrollera om
__default__inte ärtyping.NoDefaultsingleton, förutom att det inte tvingar fram utvärdering av lazily evaluated standardvärde.Tillagd i version 3.13.
Ändrad i version 3.12: Typvariabler kan nu deklareras med hjälp av syntaxen type parameter som introducerades av PEP 695. Parametern
infer_variancehar lagts till.Ändrad i version 3.13: Stöd för standardvärden har lagts till.
- class typing.TypeVarTuple(name, *, default=typing.NoDefault)¶
Typvariabel-tupel. En specialiserad form av typvariabel som möjliggör variadisk generik.
Typvariabeltuples kan deklareras i typparameterlistor med en enda asterisk (
*) före namnet:def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
Eller genom att uttryckligen anropa
TypeVarTuple-konstruktören:T = TypVar("T") Ts = TypeVarTuple("Ts") def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
En normal typvariabel möjliggör parametrisering med en enda typ. En typvariabel-tupel, däremot, tillåter parameterisering med ett viljilöst antal typer genom att fungera som ett viljilöst antal typvariabler som är förpackade i en tupel. Till exempel:
# T är bundet till int, Ts är bundet till () # Returvärdet är (1,), som har typen tuple[int] flytta_första_elementet_till_det_senaste(tup=(1,)) # T är bundet till int, Ts är bundet till (str,) # Returvärdet är ('spam', 1), som har typen tuple[str, int] move_first_element_to_last(tup=(1, 'spam')) # T är bundet till int, Ts är bundet till (str, float) # Returvärdet är ('spam', 3.0, 1), som har typen tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) # Detta misslyckas med typkontrollen (och misslyckas vid körning) # eftersom tuple[()] inte är kompatibel med tuple[T, *Ts] # (minst ett element krävs) move_first_element_to_last(tup=())
Notera användningen av uppackningsoperatorn
*ituple[T, *Ts]. Konceptuellt kan du tänka påTssom en tupel av typvariabler(T1, T2, ...).tuple[T, *Ts]skulle då blituple[T, *(T1, T2, ...)], vilket är likvärdigt medtuple[T, T1, T2, ...]. (Observera att i äldre versioner av Python kan du se detta skrivet medUnpackistället, somUnpack[Ts].)Typvariabeltuples måste alltid vara uppackade. Detta hjälper till att skilja typvariabeltuples från vanliga typvariabler:
x: Ts # Inte giltig x: tuple[Ts] # Inte giltig x: tuple[*Ts] # Det korrekta sättet att göra det
Typvariabeltuples kan användas i samma sammanhang som vanliga typvariabler. Till exempel i klassdefinitioner, argument och returtyper:
class Array[*Shape]: def __getitem__(self, key: tuple[*Shape]) -> float: ... def __abs__(self) -> "Array[*Shape]": ... def get_shape(self) -> tuple[*Shape]: ...
Typvariabeltuples kan kombineras med vanliga typvariabler:
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
Observera dock att högst en typvariabel-tupel kan förekomma i en enda lista med typargument eller typparametrar:
x: tuple[*Ts, *Ts] # Not valid class Array[*Shape, *Shape]: # Not valid pass
Slutligen kan en uppackad typvariabel-tupel användas som typannotering för
*args:def call_soon[*Ts]( återuppringning: Kallbar[[*Ts], Ingen], *args: *Ts ) -> Ingen: ... återuppringning(*args)
I motsats till icke-uppackade annoteringar av
*args- t.ex.*args: int, som skulle ange att alla argument ärint-*args: *Tsmöjliggör referens till typerna av de individuella argumenten i*args. Här tillåter detta oss att säkerställa att typerna av*argssom skickas tillcall_soonmatchar typerna av (positionella) argument icallback.Se PEP 646 för mer information om typvariabeltuples.
- __name__¶
Namnet på typvariabeln tuple.
- __default__¶
Standardvärdet för typvariabeln tuple, eller
typing.NoDefaultom den inte har något standardvärde.Tillagd i version 3.13.
- evaluate_default()¶
En evaluate function som motsvarar attributet
__default__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__default__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format.Tillagd i version 3.14.
- has_default()¶
Returnerar om typvariabeln tuple har ett standardvärde eller inte. Detta är likvärdigt med att kontrollera om
__default__inte ärtyping.NoDefaultsingleton, förutom att det inte tvingar fram utvärdering av lazily evaluated standardvärde.Tillagd i version 3.13.
Tillagd i version 3.11.
Ändrad i version 3.12: Typvariabeltuples kan nu deklareras med hjälp av syntaxen type parameter som introducerades av PEP 695.
Ändrad i version 3.13: Stöd för standardvärden har lagts till.
- class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False, default=typing.NoDefault)¶
Variabel för parameterspecifikation. En specialiserad version av typvariabler.
I type-parameterlistor kan parameterspecifikationer deklareras med två asterisker (
**):typ IntFunc[**P] = Anropsbar[P, int]
För kompatibilitet med Python 3.11 och tidigare kan
ParamSpec-objekt också skapas på följande sätt:P = ParamSpec('P')
Parameterspecifikationsvariabler är främst till för att underlätta för statiska typkontrollanter. De används för att vidarebefordra parametertyperna för en anropbar till en annan anropbar – ett mönster som är vanligt förekommande i högre ordningens funktioner och dekoratorer. De är endast giltiga när de används i
Concatenate, eller som det första argumentet tillCallable, eller som parametrar för användardefinierade Generics. SeGenericför mer information om generiska typer.Om man t.ex. vill lägga till grundläggande loggning i en funktion kan man skapa en dekorator
add_loggingför att logga funktionsanrop. Parameterspecifikationsvariabeln talar om för typkontrollen att den anropsbarhet som skickas till dekoratorn och den nya anropsbarhet som returneras av den har typparametrar som är beroende av varandra: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
Utan
ParamSpecvar det enklaste sättet att annotera detta tidigare att använda enTypeVarmed övre gränsenCallable[..., Any]. Detta orsakar dock två problem:Typkontrollen kan inte typkontrollera funktionen
innereftersom*argsoch**kwargsmåste vara typadeAny.cast()kan krävas i kroppen avadd_loggingdekoratorn när den returnerarinnerfunktionen, eller så måste den statiska typkontrollen sägas att ignorerareturn inner.
- args¶
- kwargs¶
Eftersom
ParamSpecfångar både positionella parametrar och nyckelordsparametrar kanP.argsochP.kwargsanvändas för att dela upp enParamSpeci dess komponenter.P.argsrepresenterar tupeln av positionella parametrar i ett givet anrop och bör endast användas för att annotera*args.P.kwargsrepresenterar mappningen av nyckelordsparametrar till deras värden i ett givet anrop och bör endast användas för att annotera**kwargs. Båda attributen kräver att den annoterade parametern är i scope. Vid körning ärP.argsochP.kwargsinstanser avParamSpecArgsrespektiveParamSpecKwargs.
- __name__¶
Namnet på parameterspecifikationen.
- __default__¶
Standardvärdet för parameterspecifikationen, eller
typing.NoDefaultom den inte har något standardvärde.Tillagd i version 3.13.
- evaluate_default()¶
En evaluate function som motsvarar attributet
__default__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__default__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format.Tillagd i version 3.14.
- has_default()¶
Returnerar om parameterspecifikationen har ett standardvärde eller inte. Detta är likvärdigt med att kontrollera om
__default__inte ärtyping.NoDefaultsingleton, förutom att det inte tvingar fram utvärdering av lazily evaluated standardvärde.Tillagd i version 3.13.
Parameterspecifikationsvariabler skapade med
covariant=Trueellercontravariant=Truekan användas för att deklarera kovarianta eller kontravarianta generiska typer. Argumentetboundaccepteras också, på samma sätt som förTypeVar. Den faktiska semantiken för dessa nyckelord är dock ännu inte fastställd.Tillagd i version 3.10.
Ändrad i version 3.12: Parameterspecifikationer kan nu deklareras med hjälp av syntaxen type parameter som introducerades av PEP 695.
Ändrad i version 3.13: Stöd för standardvärden har lagts till.
Anteckning
Endast parameterspecifika variabler som definieras i global omfattning kan picklas.
Se även
PEP 612 – Variabler för parameterspecifikation (PEP:n som introducerade
ParamSpecochConcatenate)Koncatenate
- typing.ParamSpecArgs¶
- typing.ParamSpecKwargs¶
Attribut för argument och nyckelordsargument för en
ParamSpec. AttributetP.argsför enParamSpecär en instans avParamSpecArgs, ochP.kwargsär en instans avParamSpecKwargs. De är avsedda för introspektion under körning och har ingen särskild betydelse för statiska typkontroller.Anrop av
get_origin()på något av dessa objekt kommer att returnera den ursprungligaParamSpec:>>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True >>> get_origin(P.kwargs) is P True
Tillagd i version 3.10.
- class typing.TypeAliasType(name, value, *, type_params=())¶
Typen av typalias som skapas genom
type-satsen.Exempel:
>>> type Alias = int >>> type(Alias) <class 'typing.TypeAliasType'>
Tillagd i version 3.12.
- __name__¶
Namnet på typaliaset:
>>> type Alias = int >>> Alias.__name__ 'Alias'
- __module__¶
Den modul där typaliaset definierades:
>>> type Alias = int >>> Alias.__module__ '__main__'
- __type_params__¶
Typparametrarna för typaliaset, eller en tom tupel om aliaset inte är generiskt:
>>> type ListOrSet[T] = list[T] | set[T] >>> ListOrSet.__type_params__ (T,) >>> type NotGeneric = int >>> NotGeneric.__type_params__ ()
- __value__¶
Typaliasets värde. Detta är lazily evaluated, så namn som används i definitionen av aliaset löses inte förrän attributet
__value__används:>>> type Mutually = Recursive >>> type Recursive = Mutually >>> Mutually Mutually >>> Recursive Recursive >>> Mutually.__value__ Recursive >>> Recursive.__value__ Mutually
- evaluate_value()¶
En evaluate function som motsvarar attributet
__value__. Vid direkt anrop stöder denna metod endast formatetVALUE, vilket motsvarar direkt åtkomst till attributet__value__, men metodobjektet kan skickas tillannotationlib.call_evaluate_function()för att utvärdera värdet i ett annat format:>>> 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')
Tillagd i version 3.14.
Uppackning
Typalias stöder uppackning av stjärnor med hjälp av syntaxen
*Alias. Detta är likvärdigt med att användaUnpack[Alias]direkt:>>> type Alias = tuple[int, str] >>> type Unpacked = tuple[bool, *Alias] >>> Unpacked.__value__ tuple[bool, typing.Unpack[Alias]]
Tillagd i version 3.14.
Andra särskilda direktiv¶
Dessa funktioner och klasser ska inte användas direkt som annotationer. Deras avsedda syfte är att vara byggstenar för att skapa och deklarera typer.
- class typing.NamedTuple¶
Typad version av
collections.namedtuple().Användning:
class Anställd(NamedTuple): name: str id: int
Detta är likvärdigt med:
Anställd = collections.namedtuple('Anställd', ['namn', 'id'])
För att ge ett fält ett standardvärde kan du tilldela det i klassen body:
class Anställd(NamedTuple): name: str id: int = 3 anställd = Anställd('Guido') assert anställd.id == 3
Fält med ett standardvärde måste komma efter alla fält utan standardvärde.
Den resulterande klassen har ett extra attribut
__annotations__som ger en dict som mappar fältnamnen till fälttyperna. (Fältnamnen finns i attributet_fieldsoch standardvärdena finns i attributet_field_defaults, som båda är en del avnamedtuple()API)NamedTuplesubklasser kan också ha docstrings och metoder:class Anställd(NamedTuple): """Representerar en anställd.""" namn: str id: int = 3 def __repr__(self) -> str: return f'<Anställd {self.name}, id={self.id}>'
NamedTuplesubklasser kan vara generiska:class Group[T](NamedTuple): nyckel: T group: lista[T]
Bakåtkompatibel användning:
# 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)])
Ändrad i version 3.6: Lagt till stöd för PEP 526 variabelannotationssyntax.
Ändrad i version 3.6.1: Stöd för standardvärden, metoder och docstrings har lagts till.
Ändrad i version 3.8: Attributen
_field_typesoch__annotations__är nu vanliga ordböcker istället för instanser avOrderedDict.Ändrad i version 3.9: Attributet
_field_typeshar tagits bort till förmån för det mer standardiserade attributet__annotations__som innehåller samma information.Ändrad i version 3.11: Lagt till stöd för generiska namntuples.
Ändrad i version 3.14: Att använda
super()(och__class__closure variable) i metoder i underklasser tillNamedTuplestöds inte och orsakar ettTypeError.Deprecated since version 3.13, will be removed in version 3.15: Den odokumenterade syntaxen med nyckelordsargument för att skapa NamedTuple-klasser (
NT = NamedTuple("NT", x=int)) är föråldrad och kommer att förbjudas i 3.15. Använd den klassbaserade syntaxen eller den funktionella syntaxen istället.Deprecated since version 3.13, will be removed in version 3.15: När du använder den funktionella syntaxen för att skapa en NamedTuple-klass är det föråldrat att inte skicka ett värde till parametern ’fields’ (
NT = NamedTuple("NT")). Att skickaNonetill parametern ’fields’ (NT = NamedTuple("NT", None)) är också föråldrat. Båda kommer att vara otillåtna i Python 3.15. För att skapa en NamedTuple-klass med 0 fält, användclass NT(NamedTuple): passellerNT = NamedTuple("NT", []).
- class typing.NewType(name, tp)¶
Hjälpklass för att skapa låga kostnader distinct types.
En
NewTypebetraktas som en distinkt typ av en typkontrollör. Vid körning returnerar dock anrop av enNewTypedess argument oförändrat.Användning:
UserId = NewType('UserId', int) # Deklarera NewType "UserId" first_user = UserId(1) # "UserId" returnerar argumentet oförändrat vid körning
- __module__¶
Den modul i vilken den nya typen definieras.
- __name__¶
Namnet på den nya typen.
- __supertype__¶
Den typ som den nya typen är baserad på.
Tillagd i version 3.5.2.
Ändrad i version 3.10:
NewTypeär nu en klass snarare än en funktion.
- class typing.Protocol(Generic)¶
Basklass för protokollklasser.
Protokollklasserna definieras på följande sätt:
class Proto(Protocol): def meth(self) -> int: ...
Sådana klasser används främst med statiska typkontrollprogram som känner igen strukturell subtypning (statisk duck-typning), t.ex:
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check
Se PEP 544 för mer information. Protokollklasser dekorerade med
runtime_checkable()(beskrivs senare) fungerar som enkla körtidsprotokoll som endast kontrollerar förekomsten av givna attribut och ignorerar deras typsignaturer. Protokollklasser utan denna dekorator kan inte användas som det andra argumentet tillisinstance()ellerissubclass().Protokollklasserna kan vara generiska, till exempel:
class GenProto[T](Protocol): def meth(self) -> T: ...
I kod som måste vara kompatibel med Python 3.11 eller äldre kan generiska protokoll skrivas på följande sätt:
T = TypeVar("T") class GenProto(Protocol[T]): def meth(self) -> T: ...
Tillagd i version 3.8.
- @typing.runtime_checkable¶
Markera en protokollklass som ett runtime-protokoll.
Ett sådant protokoll kan användas med
isinstance()ochissubclass(). Detta möjliggör en enkel strukturell kontroll, mycket lik ”one trick ponies” icollections.abcsåsomIterable. Till exempel:@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)
Denna dekorator ger upphov till
TypeErrornär den tillämpas på en icke-protokollklass.Anteckning
runtime_checkable()kontrollerar endast förekomsten av de nödvändiga metoderna eller attributen, inte deras typsignaturer eller typer. Till exempel ärssl.SSLObjecten klass, därför klarar den enissubclass()-kontroll mot Callable. Men metodenssl.SSLObject.__init__existerar bara för att ge upphov till ettTypeErrormed ett mer informativt meddelande, vilket gör det omöjligt att anropa (instansiera)ssl.SSLObject.Anteckning
En
isinstance()-kontroll mot ett protokoll som kan kontrolleras under körtiden kan vara förvånansvärt långsam jämfört med enisinstance()-kontroll mot en icke-protokollklass. Överväg att använda alternativa idiom somhasattr()-anrop för strukturella kontroller i prestandakänslig kod.Tillagd i version 3.8.
Ändrad i version 3.12: Den interna implementationen av
isinstance()-kontroller mot runtime-checkable-protokoll använder nuinspect.getattr_static()för att leta upp attribut (tidigare användeshasattr()). Som ett resultat kan vissa objekt som tidigare betraktades som instanser av ett runtime-checkable-protokoll inte längre betraktas som instanser av det protokollet på Python 3.12+, och vice versa. De flesta användare kommer troligen inte att påverkas av denna ändring.Ändrad i version 3.12: Medlemmarna i ett protokoll som kan kontrolleras vid körning betraktas nu som ”frysta” vid körning så snart klassen har skapats. Att lägga till attribut till ett protokoll som kan kontrolleras vid körning fungerar fortfarande, men har ingen inverkan på
isinstance()-kontroller som jämför objekt med protokollet. Se Vad är nytt i Python 3.12 för mer information.
- class typing.TypedDict(dict)¶
Specialkonstruktion för att lägga till typtips i en ordbok. Vid körning är det en vanlig
dict.TypedDictdeklarerar en ordbokstyp som förväntar sig att alla dess instanser ska ha en viss uppsättning nycklar, där varje nyckel är associerad med ett värde av en konsekvent typ. Denna förväntan kontrolleras inte vid körning utan verkställs endast av typkontrollanter. Användning: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')
Ett alternativt sätt att skapa en
TypedDictär att använda syntax för funktionsanrop. Det andra argumentet måste vara en bokstavligdict:Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
Denna funktionella syntax gör det möjligt att definiera nycklar som inte är giltiga identifierare, till exempel för att de är nyckelord eller innehåller bindestreck, eller när nyckelnamn inte får manglas som vanliga privata namn:
# 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
Som standard måste alla nycklar finnas i en
TypedDict. Det är möjligt att markera enskilda nycklar som icke-obligatoriska medNotRequired:class Point2D(TypedDict): x: int y: int label: NotRequired[str] # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})
Detta innebär att en
Point2DTypedDictkan ha nyckelnlabelutelämnad.Det är också möjligt att markera alla nycklar som icke nödvändiga som standard genom att ange ett antal
False:class Point2D(TypedDict, total=False): x: int y: int # Alternativ syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)
Detta innebär att en
Point2DTypedDictkan ha någon av nycklarna utelämnad. En typkontroll förväntas endast stödja en bokstavligFalseellerTruesom värdet avtotalargumentet.Trueär standard och gör att alla objekt som definieras i klassens kropp är obligatoriska.Enskilda nycklar i en
TypedDictmedtotal=Falsekan markeras som obligatoriska medRequired:class Point2D(TypedDict, total=False): x: Krävs[int] y: Krävs[int] etikett: str # Alternativ syntax Point2D = TypedDict('Point2D', { 'x': Krävs[int], 'y': Krävs[int], 'label': str }, total=False)
Det är möjligt för en typ av
TypedDictatt ärva från en eller flera andra typer avTypedDictmed hjälp av den klassbaserade syntaxen. Användning:class Point3D(Point2D): z: int
Point3Dhar tre objekt:x,yochz. Den är ekvivalent med denna definition:class Point3D(TypedDict): x: int y: int z: int
En
TypedDictkan inte ärva från en ickeTypedDict-klass, förutomGeneric`. Till exempel: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
En
TypedDictkan vara generisk:class Group[T](TypedDict): nyckel: T group: lista[T]
För att skapa en generisk
TypedDictsom är kompatibel med Python 3.11 eller lägre, ärva frånGenericexplicit:T = TypeVar("T") class Group(TypedDict, Generic[T]): key: T group: list[T]
En
TypedDictkan introspekteras via annotationsdict (se Bästa praxis för annoteringar för mer information om bästa praxis för annotationer),__total__,__required_keys__och__optional_keys__.- __total__¶
Point2D.__total__ger värdet av argumentettotal. Exempel:>>> 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
Detta attribut återspeglar endast värdet av argumentet
totalför den aktuella klassenTypedDict, inte om klassen är semantiskt total. Till exempel kan enTypedDictmed__total__inställd påTrueha nycklar markerade medNotRequired, eller så kan den ärva från en annanTypedDictmedtotal=False. Därför är det i allmänhet bättre att använda__required_keys__och__optional_keys__för introspektion.
- __required_keys__¶
Tillagd i version 3.9.
- __optional_keys__¶
Point2D.__required_keys__ochPoint2D.__optional_keys__returnerarfrozenset-objekt som innehåller obligatoriska respektive icke-obligatoriska nycklar.Nycklar som är markerade med
Requiredkommer alltid att visas i__required_keys__och nycklar som är markerade medNotRequired`kommer alltid att visas i__optional_keys__.För bakåtkompatibilitet med Python 3.10 och lägre är det också möjligt att använda arv för att deklarera både obligatoriska och icke-obligatoriska nycklar i samma
TypedDict. Detta görs genom att deklarera enTypedDictmed ett värde för argumentettotaloch sedan ärva från den i en annanTypedDictmed ett annat värde förtotal:>>> 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
Tillagd i version 3.9.
Anteckning
Om
from __future__ import annotationsanvänds eller om annoteringar anges som strängar, utvärderas inte annoteringarna närTypedDictdefinieras. Därför kan det hända att den introspektion under körning som__required_keys__och__optional_keys__förlitar sig på inte fungerar korrekt, och attributens värden kan vara felaktiga.
Stöd för
ReadOnlyåterspeglas i följande attribut:- __readonly_keys__¶
En
frozensetsom innehåller namnen på alla skrivskyddade nycklar. Nycklar är skrivskyddade om de harReadOnly-kvalificeraren.Tillagd i version 3.13.
- __mutable_keys__¶
En
frozensetsom innehåller namnen på alla mutabla nycklar. Nycklar är mutabla om de inte harReadOnly-kvalificeraren.Tillagd i version 3.13.
Se avsnittet TypedDict i typningsdokumentationen för fler exempel och detaljerade regler.
Tillagd i version 3.8.
Ändrad i version 3.11: Lagt till stöd för att markera enskilda nycklar som
RequiredellerNotRequired. Se PEP 655.Ändrad i version 3.11: Lagt till stöd för generiska
TypedDict.Ändrad i version 3.13: Borttaget stöd för nyckelord-argument-metoden för att skapa
TypedDict.Ändrad i version 3.13: Stöd för kvalifikatorn
ReadOnlyhar lagts till.Deprecated since version 3.13, will be removed in version 3.15: När du använder den funktionella syntaxen för att skapa en TypedDict-klass är det föråldrat att inte skicka ett värde till parametern ’fields’ (
TDD = TypedDict("TD")). Att skickaNonetill parametern ’fields’ (TD = TypedDict("TD", None)) är också föråldrat. Båda kommer att vara otillåtna i Python 3.15. För att skapa en TypedDict-klass med 0 fält, användclass TD(TypedDict): passellerTD = TypedDict("TD", {}).
Protokoll¶
Följande protokoll tillhandahålls av modulen typing. Alla är dekorerade med @runtime_checkable.
- class typing.SupportsAbs¶
En ABC med en abstrakt metod
__abs__som är kovariant i sin returtyp.
- class typing.SupportsBytes¶
En ABC med en abstrakt metod
__bytes__.
- class typing.SupportsComplex¶
En ABC med en abstrakt metod
__complex__.
- class typing.SupportsFloat¶
En ABC med en abstrakt metod
__float__.
- class typing.SupportsIndex¶
En ABC med en abstrakt metod
__index__.Tillagd i version 3.8.
- class typing.SupportsInt¶
En ABC med en abstrakt metod
__int__.
- class typing.SupportsRound¶
En ABC med en abstrakt metod
__round__som är kovariant i sin returtyp.
ABC och protokoll för att arbeta med I/O¶
- class typing.IO[AnyStr]¶
- class typing.TextIO[AnyStr]¶
- class typing.BinaryIO[AnyStr]¶
Den generiska klassen
IO[AnyStr]och dess underklasserTextIO(IO[str])ochBinaryIO(IO[bytes])representerar de typer av I/O-strömmar som returneras avopen(). Observera att dessa klasser inte är protokoll och att deras gränssnitt är ganska brett.
Protokollen io.Reader och io.Writer erbjuder ett enklare alternativ för argumenttyper, när endast metoderna read() respektive write() används:
def read_and_write(reader: Reader[str], writer: Writer[bytes]):
data = reader.read()
writer.write(data.encode())
Överväg också att använda collections.abc.Iterable för att iterera över raderna i en inmatningsström:
def read_config(stream: Iterable[str]):
för rad i ström:
...
Funktioner och dekoratorer¶
- typing.cast(typ, val)¶
Kasta ett värde till en typ.
Detta returnerar värdet oförändrat. För typkontrollanten signalerar detta att returvärdet har den angivna typen, men vid körning kontrollerar vi avsiktligt ingenting (vi vill att det ska gå så snabbt som möjligt).
- typing.assert_type(val, typ, /)¶
Be en statisk typkontrollör att bekräfta att val har en härledd typ av typ.
Vid körning gör detta ingenting: det returnerar det första argumentet oförändrat utan kontroller eller sidoeffekter, oavsett argumentets faktiska typ.
När en statisk typkontrollör stöter på ett anrop till
assert_type(), avger den ett fel om värdet inte är av den angivna typen:def greet(namn: str) -> None: assert_type(name, str) # OK, den härledda typen av `namn` är `str` assert_type(name, int) # fel i typkontrollen
Denna funktion är användbar för att säkerställa att typkontrollantens förståelse av ett skript är i linje med utvecklarens avsikter:
def komplex_funktion(arg: objekt): # Gör en del komplex logik för typbegränsning, # varefter vi hoppas att den härledda typen kommer att vara `int` ... # Testa om typkontrollen förstår vår funktion korrekt assert_type(arg, int)
Tillagd i version 3.11.
- typing.assert_never(arg, /)¶
Be en statisk typkontroll att bekräfta att en kodrad är oåtkomlig.
Exempel:
def int_or_str(arg: int | str) -> None: matcha arg: fall int(): print("Det är en int") fall str(): print("Det är en str") fall _ som oåtkomlig: assert_never(oåtkomlig)
Här gör annotationerna det möjligt för typkontrollen att dra slutsatsen att det sista fallet aldrig kan utföras, eftersom
argantingen är eninteller enstr, och båda alternativen täcks av tidigare fall.Om en typkontrollör upptäcker att ett anrop till
assert_never()är nåbart, kommer den att avge ett felmeddelande. Till exempel, om typannoteringen förargistället varint | str | float, skulle typkontrollen avge ett felmeddelande som påpekar attunreachableär av typenfloat. För att ett anrop tillassert_neverska klara typkontrollen måste den härledda typen av argumentet som skickas in vara bottentypen,Never, och inget annat.Vid körning kastar detta ett undantag när det anropas.
Se även
i Unreachable Code and Exhaustiveness Checking finns mer information om kontroll av fullständighet med statisk typning.
Tillagd i version 3.11.
- typing.reveal_type(obj, /)¶
Be en statisk typkontrollör att avslöja den härledda typen för ett uttryck.
När en statisk typkontrollör stöter på ett anrop till denna funktion avger den en diagnostik med den härledda typen av argumentet. Till exempel:
x: int = 1 reveal_type(x) # Avslöjad typ är "builtins.int"
Detta kan vara användbart när du vill felsöka hur din typkontroll hanterar en viss kod.
Vid körning skriver denna funktion ut körtidstypen för sitt argument till
sys.stderroch returnerar argumentet oförändrat (vilket gör att anropet kan användas inom ett uttryck):x = reveal_type(1) # skriver ut "Körtidstypen är int" print(x) # skriver ut "1"
Observera att körtidstypen kan skilja sig från (mer eller mindre specifik än) den typ som statiskt härleds av en typkontroll.
De flesta typkontrollprogram stöder
reveal_type()var som helst, även om namnet inte importeras fråntyping. Att importera namnet fråntypinggör dock att din kod kan köras utan körtidsfel och kommunicerar avsikten tydligare.Tillagd i version 3.11.
- @typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)¶
Dekorator för att markera att ett objekt har ett
dataklass-liknande beteende.dataclass_transformkan användas för att dekorera en klass, metaklass eller en funktion som i sig är en dekorator. Närvaron av@dataclass_transform()talar om för en statisk typkontrollant att det dekorerade objektet utför ”magi” under körning som transformerar en klass på ett liknande sätt som@dataclasses.dataclass.Exempel på användning med en dekoratorfunktion:
@dataclass_transform() def create_model[T](cls: type[T]) -> type[T]: ... return cls @create_model class CustomerModel: id: int name: str
På en basklass:
@dataclass_transform() class ModelBase: ... class CustomerModel(ModelBase): id: int name: str
På en metaklass:
@dataclass_transform() class ModelMeta(type): ... class ModelBase(metaclass=ModelMeta): ... class CustomerModel(ModelBase): id: int name: str
Klasserna
CustomerModelsom definieras ovan kommer att behandlas av typkontrollprogram på samma sätt som klasser som skapats med@dataclasses.dataclass. Exempelvis kommer typkontrollerna att anta att dessa klasser har__init__-metoder som accepteraridochname.Den dekorerade klassen, metaklassen eller funktionen kan acceptera följande bool-argument som typkontrollanter kommer att anta har samma effekt som de skulle ha på
@dataclasses.dataclass-dekoratorn:init,eq,order,unsafe_hash,frozen,match_args,kw_onlyochslots. Det måste vara möjligt att statiskt utvärdera värdet av dessa argument (TrueellerFalse).Argumenten till dekoratorn
dataclass_transformkan användas för att anpassa standardbeteendena för den dekorerade klassen, metaklassen eller funktionen:- Parametrar:
eq_default (bool) – Anger om parametern
eqska antas varaTrueellerFalseom den utelämnas av anroparen. Standardvärdet ärTrue.order_default (bool) – Anger om parametern
orderska antas varaTrueellerFalseom den utelämnas av den som anropar. Standardvärdet ärFalse.kw_only_default (bool) – Anger om parametern
kw_onlyska antas varaTrueellerFalseom den utelämnas av den som anropar. Standardvärdet ärFalse.frozen_default (bool) – Anger om parametern
frozenska antas varaTrueellerFalseom den utelämnas av den som anropar. Standardvärdet ärFalse. .. versionadded:: 3.12field_specifiers (tuple[Callable[..., Any], ...]) – Anger en statisk lista över klasser eller funktioner som stöds och som beskriver fält, liknande
dataclasses.field(). Standardvärdet är().**kwargs (Any) – Godtyckliga andra nyckelordsargument accepteras för att möjliggöra eventuella framtida tillägg.
Typkontroller känner igen följande valfria parametrar på fältspecifikatorer:
Erkända parametrar för fältangivelser¶ Parameternamn
Beskrivning
initAnger om fältet ska ingå i den syntetiserade metoden
__init__. Om inget anges ärinitstandardvärdetTrue.standardAnger standardvärdet för fältet.
standard_fabrikTillhandahåller ett runtime callback som returnerar standardvärdet för fältet. Om varken
defaultellerdefault_factoryanges, antas fältet inte ha något standardvärde och måste förses med ett värde när klassen instansieras.”fabrik
Ett alias för parametern
default_factorypå fältspecifikatorer.kw_onlyAnger om fältet ska markeras som endast nyckelord. Om
True, kommer fältet att vara nyckelordsskyddat. OmFalse, kommer det inte att vara nyckelordsskyddat. Om det är ospecificerat, kommer värdet på parameternkw_onlypå objektet som dekorerats meddataclass_transformatt användas, eller om det är ospecificerat, kommer värdet påkw_only_defaultpådataclass_transformatt användas.aliasAnger ett alternativt namn för fältet. Detta alternativa namn används i den syntetiserade metoden
__init__.Vid körning registrerar denna dekorator sina argument i attributet
__dataclass_transform__på det dekorerade objektet. Den har ingen annan effekt under körning.Se PEP 681 för mer information.
Tillagd i version 3.11.
- @typing.overload¶
Dekorator för att skapa överladdade funktioner och metoder.
Dekoratorn
@overloadgör det möjligt att beskriva funktioner och metoder som stöder flera olika kombinationer av argumenttyper. En serie definitioner med dekoratorn@overloadmåste följas av exakt en definition utan dekoratorn@overload(för samma funktion/metod).Definitioner med @overload-dekoration är endast till för typkontroll, eftersom de kommer att skrivas över av definitioner utan @overload-dekoration. Definitioner utan @overload-dekoration kommer däremot att användas vid körning, men bör ignoreras av typkontrollen. Vid körning kommer ett direkt anrop av en funktion med @overload-dekoration att generera
NotImplementedError.Ett exempel på överbelastning som ger en mer exakt typ än vad som kan uttryckas med hjälp av en union eller en typvariabel:
@överbelastning def process(svar: None) -> None: ... @överbelastning def process(response: int) -> tuple[int, str]: ... @överbelastning def process(svar: bytes) -> str: ... def process(svar): ... # faktisk implementering går här
Se PEP 484 för mer information och jämförelse med annan typningssemantik.
Ändrad i version 3.11: Överladdade funktioner kan nu introspekteras vid körning med
get_overloads().
- typing.get_overloads(func)¶
Returnerar en sekvens av
@overload-dekorerade definitioner för func.func är funktionsobjektet för implementeringen av den överladdade funktionen. Till exempel, givet definitionen av
processi dokumentationen för@overload, kommerget_overloads(process)att returnera en sekvens av tre funktionsobjekt för de tre definierade överbelastningarna. Om den anropas på en funktion utan överbelastningar returnerarget_overloads()en tom sekvens.get_overloads()kan användas för att introspektera en överbelastad funktion under körning.Tillagd i version 3.11.
- typing.clear_overloads()¶
Rensa alla registrerade överbelastningar i det interna registret.
Detta kan användas för att återta det minne som används av registret.
Tillagd i version 3.11.
- @typing.final¶
Dekorator för att ange slutgiltiga metoder och slutgiltiga klasser.
Att dekorera en metod med
@finalindikerar för en typkontrollant att metoden inte kan åsidosättas i en underklass. Att dekorera en klass med@finalindikerar att den inte kan subklassas.Till exempel:
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 ...
Det finns ingen körtidskontroll av dessa egenskaper. Se PEP 591 för mer information.
Tillagd i version 3.8.
Ändrad i version 3.11: Dekoratorn kommer nu att försöka sätta attributet
__final__tillTruepå det dekorerade objektet. Således kan en kontroll somif getattr(obj, "__final__", False)användas vid runtime för att avgöra om ett objektobjhar markerats som final. Om det dekorerade objektet inte har stöd för att sätta attribut, returnerar dekoratorn objektet oförändrat utan att skapa ett undantag.
- @typing.no_type_check¶
Dekorator för att ange att annotationer inte är typtips.
Detta fungerar som en klass eller funktion decorator. För en klass gäller den rekursivt för alla metoder och klasser som definieras i den klassen (men inte för metoder som definieras i dess superklasser eller subklasser). Typkontrollanter ignorerar alla annoteringar i en funktion eller klass med denna dekorator.
@no_type_checkmuterar det dekorerade objektet på plats.
- @typing.no_type_check_decorator¶
Dekorator för att ge en annan dekorator
no_type_check()-effekten.Detta omsluter dekoratorn med något som omsluter den dekorerade funktionen i
no_type_check().Deprecated since version 3.13, will be removed in version 3.15: Ingen typkontroll har någonsin lagt till stöd för
@no_type_check_decorator. Det är därför föråldrat och kommer att tas bort i Python 3.15.
- @typing.override¶
Dekorator för att ange att en metod i en subklass är avsedd att åsidosätta en metod eller ett attribut i en superklass.
Typkontroller bör avge ett felmeddelande om en metod som dekorerats med
@overridei själva verket inte åsidosätter något. Detta hjälper till att förhindra buggar som kan uppstå när en basklass ändras utan att en underordnad klass ändras på motsvarande sätt.Till exempel:
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 ...
Det finns ingen runtime-kontroll av denna egenskap.
Dekoratorn kommer att försöka sätta ett
__override__attribut tillTruepå det dekorerade objektet. Således kan en kontroll somif getattr(obj, "__override__", False)användas vid körning för att avgöra om ett objektobjhar markerats som en åsidosättning. Om det dekorerade objektet inte har stöd för att ställa in attribut, returnerar dekoratorn objektet oförändrat utan att skapa ett undantag.Se PEP 698 för mer information.
Tillagd i version 3.12.
- @typing.type_check_only¶
Dekorator för att markera att en klass eller funktion inte är tillgänglig vid körning.
Denna dekorator är i sig inte tillgänglig vid körning. Den är främst avsedd att markera klasser som definieras i typstub-filer om en implementation returnerar en instans av en privat klass:
@typ_kontroll_endast klass Svar: # privat eller inte tillgänglig vid körning kod: int def get_header(self, name: str) -> str: ... def fetch_response() -> Svar: ...
Observera att det inte är rekommenderat att returnera instanser av privata klasser. Det är oftast att föredra att göra sådana klasser publika.
Hjälpmedel för introspektion¶
- typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False)¶
Returnerar en dictionary som innehåller typtips för en funktion, metod, modul eller klassobjekt.
Detta är ofta samma sak som
obj.__annotations__, men denna funktion gör följande ändringar i annotationsordlistan:Framåtriktade referenser som kodas som stränglitteraler eller
ForwardRef-objekt hanteras genom att de utvärderas i globalns, localns och (i förekommande fall) obj:s typparameter namnrymd. Om globalns eller localns inte anges, härleds lämpliga namnrymdsordböcker från obj.Noneersätts medtypes.NoneType.Om
@no_type_checkhar tillämpats på obj returneras en tom ordbok.Om obj är en klass
Creturnerar funktionen en ordbok som sammanfogar anteckningar frånCbasklasser med dem påCdirekt. Detta görs genom att traverseraC.__mro__och iterativt kombinera__annotations__dictionaries. Anteckningar om klasser som förekommer tidigare i method resolution order har alltid företräde framför anteckningar om klasser som förekommer senare i metodupplösningsordningen.Funktionen ersätter rekursivt alla förekomster av
Annotated[T, ...]medT, såvida inte include_extras är satt tillTrue(seAnnotatedför mer information).
Se även
annotationlib.get_annotations(), en funktion på lägre nivå som returnerar annoteringar mer direkt.Anteckning
Om några framåtriktade referenser i annoteringarna för obj inte kan lösas eller inte är giltig Python-kod, kommer denna funktion att ge upphov till ett undantag som
NameError. Detta kan till exempel hända med importerade type aliases som innehåller framåtriktade referenser, eller med namn som importeras underif TYPE_CHECKING.Ändrad i version 3.9: Lade till parametern
include_extrassom en del av PEP 593. Se dokumentationen förAnnotatedför mer information.Ändrad i version 3.11: Tidigare lades
Optional[t]till för funktions- och metodannoteringar om ett standardvärde som var lika medNoneangavs. Nu returneras annoteringen oförändrad.
- typing.get_origin(tp)¶
Hämta den osubscripterade versionen av en typ: för ett typobjekt av formen
X[Y, Z, ...]returnerasX.Om
Xär ett typing-module alias för en inbyggd klass ellercollectionsklass, kommer den att normaliseras till den ursprungliga klassen. OmXär en instans avParamSpecArgsellerParamSpecKwargs, returneras den underliggandeParamSpec. ReturnerarNoneför objekt som inte stöds.Exempel:
assert get_origin(str) är ingen assert get_origin(Dict[str, int]) är dict assert get_origin(Union[int, str]) är Union assert get_origin(Annotated[str, "metadata"]) is Annotated P = ParamSpec('P') assert get_origin(P.args) is P assert get_origin(P.kwargs) är P
Tillagd i version 3.8.
- typing.get_args(tp)¶
Hämta typargument med alla substitutioner utförda: för ett typobjekt av formen
X[Y, Z, ...]returneras(Y, Z, ...).Om
Xär en union ellerLiteralsom ingår i en annan generisk typ, kan ordningen på(Y, Z, ...)skilja sig från ordningen på de ursprungliga argumenten[Y, Z, ...]på grund av typcaching. Returnera()för objekt som inte stöds.Exempel:
assert get_args(int) == () assert get_args(Dict[int, str]) == (int, str) assert get_args(Union[int, str]) == (int, str)
Tillagd i version 3.8.
- typing.get_protocol_members(tp)¶
Returnerar den uppsättning medlemmar som definieras i en
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
Utlös
TypeErrorför argument som inte är protokoll.Tillagd i version 3.13.
- typing.is_protocol(tp)¶
Avgör om en typ är en
Protocol.Till exempel:
class P(Protocol): def a(self) -> str: ... b: int is_protocol(P) # => True is_protocol(int) # => False
Tillagd i version 3.13.
- typing.is_typeddict(tp)¶
Kontrollera om en typ är en
TypedDict.Till exempel:
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)
Tillagd i version 3.10.
- class typing.ForwardRef¶
Klass som används för intern typningsrepresentation av strängens framåtriktade referenser.
Exempelvis omvandlas
List["SomeClass"]implicit tillList[ForwardRef("SomeClass")].ForwardRefbör inte instansieras av en användare, men kan användas av introspektionsverktyg.Anteckning
PEP 585 generiska typer som
list["SomeClass"]kommer inte att implicit transformeras tilllist[ForwardRef("SomeClass")]och kommer därför inte automatiskt att lösas upp tilllist[SomeClass].Tillagd i version 3.7.4.
Ändrad i version 3.14: Detta är nu ett alias för
annotationlib.ForwardRef. Flera odokumenterade beteenden hos denna klass har ändrats; till exempel, efter att enForwardRefhar utvärderats, cachelagras inte längre det utvärderade värdet.
- typing.evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)¶
Utvärdera en
annotationlib.ForwardRefsom en type hint.Detta liknar anropet av
annotationlib.ForwardRef.evaluate(), men till skillnad från den metoden utvärderarevaluate_forward_ref()även framåtriktade referenser som är kapslade i typtipset rekursivt.Se dokumentationen för
annotationlib.ForwardRef.evaluate()för betydelsen av parametrarna owner, globals, locals, type_params och format.Tillagd i version 3.14.
- typing.NoDefault¶
Ett sentinel-objekt som används för att ange att en typ-parameter inte har något standardvärde. Ett exempel:
>>> T = TypeVar("T") >>> T.__default__ is typing.NoDefault True >>> S = TypeVar("S", default=None) >>> S.__default__ is None True
Tillagd i version 3.13.
Konstant¶
- typing.TYPE_CHECKING¶
En speciell konstant som antas vara
Trueav statiska typkontrollanter från tredje part. Den ärFalsevid runtime.En modul som är dyr att importera och som endast innehåller typer som används för typannoteringar kan importeras säkert inuti ett
if TYPE_CHECKING:-block. Detta förhindrar att modulen faktiskt importeras vid körning; annoteringar utvärderas inte ivrigt (se PEP 649) så det är ofarligt att använda odefinierade symboler i annoteringar – så länge du inte undersöker dem senare. Ditt statiska typanalysverktyg kommer att ställa inTYPE_CHECKINGtillTrueunder statisk typanalys, vilket innebär att modulen kommer att importeras och typerna kommer att kontrolleras korrekt under sådan analys.Användning:
om TYPE_CHECKING: import dyr_mod def fun(arg: expensive_mod.SomeType) -> None: local_var: expensive_mod.AnotherType = other_fun()
Om du ibland behöver undersöka typannoteringar vid körning som kan innehålla odefinierade symboler, använd
annotationlib.get_annotations()med enformatparameter avannotationlib.Format.STRINGellerannotationlib.Format.FORWARDREFför att säkert hämta annoteringarna utan att ge upphov tillNameError.Tillagd i version 3.5.2.
Föråldrade alias¶
Denna modul definierar flera föråldrade alias till redan existerande standardbiblioteksklasser. Dessa ingick ursprungligen i modulen typing för att stödja parametrisering av dessa generiska klasser med hjälp av []. Aliasen blev dock överflödiga i Python 3.9 när de motsvarande befintliga klasserna förbättrades för att stödja [] (se PEP 585).
De överflödiga typerna är föråldrade från och med Python 3.9. Men även om alias kan tas bort vid någon tidpunkt, är det för närvarande inte planerat att ta bort dessa alias. Därför utfärdas för närvarande inga deprecation-varningar av tolken för dessa alias.
Om det vid någon tidpunkt beslutas att ta bort dessa föråldrade aliaser, kommer en varning om föråldring att utfärdas av tolken i minst två utgåvor innan borttagningen. Aliasen kommer garanterat att finnas kvar i typing-modulen utan deprecation-varningar fram till åtminstone Python 3.14.
Typkontrollanter uppmanas att flagga användningar av de föråldrade typerna om programmet de kontrollerar riktar sig till en minsta Python-version av 3.9 eller nyare.
Aliaser till inbyggda typer¶
- class typing.Dict(dict, MutableMapping[KT, VT])¶
Föråldrat alias till
dict.Observera att för att annotera argument är det bättre att använda en abstrakt samlingstyp som
Mappingän att användadictellertyping.Dict.Föråldrad sedan version 3.9:
builtins.dictnow supports subscripting ([]). See PEP 585 and Generisk aliastyp.
- class typing.List(list, MutableSequence[T])¶
Föråldrat alias till
list.Observera att för att annotera argument är det bättre att använda en abstrakt samlingstyp som
SequenceellerIterableän att användalistellertyping.List.Föråldrad sedan version 3.9:
builtins.liststöder nu subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Set(set, MutableSet[T])¶
Föråldrat alias till
builtins.set.Observera att för att annotera argument är det bättre att använda en abstrakt samlingstyp som
collections.abc.Setän att användasetellertyping.Set.Föråldrad sedan version 3.9:
builtins.setnow supports subscripting ([]). See PEP 585 and Generisk aliastyp.
- class typing.FrozenSet(frozenset, AbstractSet[T_co])¶
Föråldrat alias till
builtins.frozenset.Föråldrad sedan version 3.9:
builtins.frozensethar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- typing.Tuple¶
Föråldrat alias för
tuple.tupleochTupleär specialfall i typsystemet; se Annotering av tuples för mer information.Föråldrad sedan version 3.9:
builtins.tuplenow supports subscripting ([]). See PEP 585 and Generisk aliastyp.
- class typing.Type(Generic[CT_co])¶
Föråldrat alias till
type.Se Typ av klassobjekt för detaljer om hur man använder
typeellertyping.Typei typannoteringar.Tillagd i version 3.5.2.
Föråldrad sedan version 3.9:
builtins.typestöder nu subskription ([]). Se PEP 585 och Generisk aliastyp.
Alias till typer i samlingar¶
- class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])¶
Föråldrat alias till
collections.defaultdict.Tillagd i version 3.5.2.
Föråldrad sedan version 3.9:
collections.defaultdicthar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])¶
Föråldrat alias till
collections.OrderedDict.Tillagd i version 3.7.2.
Föråldrad sedan version 3.9:
collections.OrderedDicthar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])¶
Föråldrat alias till
collections.ChainMap.Tillagd i version 3.6.1.
Föråldrad sedan version 3.9:
collections.ChainMaphar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Counter(collections.Counter, Dict[T, int])¶
Föråldrat alias till
collections.Counter.Tillagd i version 3.6.1.
Föråldrad sedan version 3.9:
collections.Counterhar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Deque(deque, MutableSequence[T])¶
Föråldrat alias till
collections.deque.Tillagd i version 3.6.1.
Föråldrad sedan version 3.9:
collections.dequehar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
Alias till andra konkreta typer¶
- class typing.Pattern¶
- class typing.Match¶
Föråldrade alias som motsvarar returtyperna från
re.compile()ochre.match().Dessa typer (och motsvarande funktioner) är generiska över
AnyStr.Patternkan specialiseras somPattern[str]ellerPattern[bytes];Matchkan specialiseras somMatch[str]ellerMatch[bytes].Föråldrad sedan version 3.9: Klasserna
PatternochMatchfrånrehar nu stöd för[]. Se PEP 585 och Generisk aliastyp.
- class typing.Text¶
Föråldrat alias för
str.Texttillhandahålls för att tillhandahålla en framåtkompatibel sökväg för Python 2-kod: i Python 2 ärTextett alias förunicode.Använd
Textför att ange att ett värde måste innehålla en unicode-sträng på ett sätt som är kompatibelt med både Python 2 och Python 3:def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
Tillagd i version 3.5.2.
Föråldrad sedan version 3.11: Python 2 stöds inte längre, och de flesta typkontrollprogram stöder inte heller längre typkontroll av Python 2-kod. Det är för närvarande inte planerat att ta bort aliaset, men användare uppmuntras att använda
stristället förText.
Alias till container ABC i collections.abc¶
- class typing.AbstractSet(Collection[T_co])¶
Föråldrat alias till
collections.abc.Set.Föråldrad sedan version 3.9:
collections.abc.Sethar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Collection(Sized, Iterable[T_co], Container[T_co])¶
Föråldrat alias till
collections.abc.Collection.Tillagd i version 3.6.
Föråldrad sedan version 3.9:
collections.abc.Collectionhar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Container(Generic[T_co])¶
Föråldrat alias till
collections.abc.Container.Föråldrad sedan version 3.9:
collections.abc.Containerhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])¶
Föråldrat alias till
collections.abc.ItemsView.Föråldrad sedan version 3.9:
collections.abc.ItemsViewstöder nu subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.KeysView(MappingView, AbstractSet[KT_co])¶
Föråldrat alias till
collections.abc.KeysView.Föråldrad sedan version 3.9:
collections.abc.KeysViewhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Mapping(Collection[KT], Generic[KT, VT_co])¶
Föråldrat alias till
collections.abc.Mapping.Föråldrad sedan version 3.9:
collections.abc.Mappinghar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.MappingView(Sized)¶
Föråldrat alias till
collections.abc.MappingView.Föråldrad sedan version 3.9:
collections.abc.MappingViewstöder nu subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.MutableMapping(Mapping[KT, VT])¶
Föråldrat alias till
collections.abc.MutableMapping.Föråldrad sedan version 3.9:
collections.abc.MutableMappinghar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.MutableSequence(Sequence[T])¶
Föråldrat alias till
collections.abc.MutableSequence.Föråldrad sedan version 3.9:
collections.abc.MutableSequencehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.MutableSet(AbstractSet[T])¶
Föråldrat alias till
collections.abc.MutableSet.Föråldrad sedan version 3.9:
collections.abc.MutableSethar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Sequence(Reversible[T_co], Collection[T_co])¶
Föråldrat alias till
collections.abc.Sequence.Föråldrad sedan version 3.9:
collections.abc.Sequencehar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.
- class typing.ValuesView(MappingView, Collection[_VT_co])¶
Föråldrat alias till
collections.abc.ValuesView.Föråldrad sedan version 3.9:
collections.abc.ValuesViewstöder nu subskription ([]). Se PEP 585 och Generisk aliastyp.
Aliaser till asynkrona ABC i collections.abc¶
- class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])¶
Föråldrat alias till
collections.abc.Coroutine.Se Annotering av generatorer och coroutines för detaljer om hur man använder
collections.abc.Coroutineochtyping.Coroutinei typannoteringar.Tillagd i version 3.5.3.
Föråldrad sedan version 3.9:
collections.abc.Coroutinehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])¶
Föråldrat alias till
collections.abc.AsyncGenerator.Se Annotering av generatorer och coroutines för detaljer om hur du använder
collections.abc.AsyncGeneratorochtyping.AsyncGeneratori typannoteringar.Tillagd i version 3.6.1.
Föråldrad sedan version 3.9:
collections.abc.AsyncGeneratorhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.Ändrad i version 3.13: Parametern
SendTypehar nu en standard.
- class typing.AsyncIterable(Generic[T_co])¶
Föråldrat alias till
collections.abc.AsyncIterable.Tillagd i version 3.5.2.
Föråldrad sedan version 3.9:
collections.abc.AsyncIterablehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.AsyncIterator(AsyncIterable[T_co])¶
Föråldrat alias till
collections.abc.AsyncIterator.Tillagd i version 3.5.2.
Föråldrad sedan version 3.9:
collections.abc.AsyncIteratorhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Awaitable(Generic[T_co])¶
Föråldrat alias till
collections.abc.Awaitable.Tillagd i version 3.5.2.
Föråldrad sedan version 3.9:
collections.abc.Awaitablehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
Alias till andra ABC i collections.abc¶
- class typing.Iterable(Generic[T_co])¶
Föråldrat alias till
collections.abc.Iterable.Föråldrad sedan version 3.9:
collections.abc.Iterablehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Iterator(Iterable[T_co])¶
Föråldrat alias till
collections.abc.Iterator.Föråldrad sedan version 3.9:
collections.abc.Iteratorhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- typing.Callable¶
Föråldrat alias till
collections.abc.Callable.Se Annotering av anropsbara objekt för detaljer om hur man använder
collections.abc.Callableochtyping.Callablei typannoteringar.Föråldrad sedan version 3.9:
collections.abc.Callablehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.Ändrad i version 3.10:
Callablestöder nuParamSpecochConcatenate. Se PEP 612 för mer information.
- class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])¶
Föråldrat alias till
collections.abc.Generator.Se Annotering av generatorer och coroutines för detaljer om hur man använder
collections.abc.Generatorochtyping.Generatori typannoteringar.Föråldrad sedan version 3.9:
collections.abc.Generatorhar nu stöd för subskription ([]). Se PEP 585 och Generisk aliastyp.Ändrad i version 3.13: Standardvärden för send- och return-typerna har lagts till.
- class typing.Hashable¶
Föråldrat alias till
collections.abc.Hashable.Föråldrad sedan version 3.12: Använd
collections.abc.Hashabledirekt istället.
- class typing.Reversible(Iterable[T_co])¶
Föråldrat alias till
collections.abc.Reversible.Föråldrad sedan version 3.9:
collections.abc.Reversiblehar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.
- class typing.Sized¶
Föråldrat alias till
collections.abc.Sized.Föråldrad sedan version 3.12: Använd
collections.abc.Sizeddirekt istället.
Aliaser till contextlib ABC¶
- class typing.ContextManager(Generic[T_co, ExitT_co])¶
Föråldrat alias till
contextlib.AbstractContextManager.Den första typparametern,
T_co, representerar den typ som returneras av metoden__enter__(). Den valfria andra typ-parametern,ExitT_co, som som standard ärbool | None, representerar den typ som returneras av metoden__exit__().Tillagd i version 3.5.4.
Föråldrad sedan version 3.9:
contextlib.AbstractContextManagerhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.Ändrad i version 3.13: Lagt till den valfria andra typparametern,
ExitT_co.
- class typing.AsyncContextManager(Generic[T_co, AExitT_co])¶
Föråldrat alias till
contextlib.AbstractAsyncContextManager.Den första typparametern,
T_co, representerar den typ som returneras av metoden__aenter__(). Den valfria andra typ-parametern,AExitT_co, som som standard ärbool | None, representerar den typ som returneras av metoden__aexit__().Tillagd i version 3.6.2.
Föråldrad sedan version 3.9:
contextlib.AbstractAsyncContextManagerhar nu stöd för subscripting ([]). Se PEP 585 och Generisk aliastyp.Ändrad i version 3.13: Den valfria andra typparametern
AExitT_cohar lagts till.
Tidslinje för utfasning av viktiga funktioner¶
Vissa funktioner i typing är föråldrade och kan tas bort i en framtida version av Python. Följande tabell sammanfattar större föråldringar för din bekvämlighet. Detta kan komma att ändras, och alla föråldringar är inte listade.
Funktion |
Utfasad i |
Förväntat borttagande |
PEP/fråga |
|---|---|---|---|
|
3.9 |
Obestämd (se Föråldrade alias för mer information) |
|
3.11 |
Väntande |
||
3.12 |
Väntande |
||
3.12 |
Väntande |
||
3.13 |
3.15 |
||
|
3.13 |
3.18 |