typing — Unterstützung für Typ-Hinweise¶
Hinzugefügt in Version 3.5.
Quellcode: Lib/typing.py
Hinweis
Die Python-Laufzeit erzwingt Funktions- und Variablen-Typannotationen nicht. Sie können von Drittanbieter-Tools wie Typüberprüfern, IDEs, Lintern usw. verwendet werden.
Dieses Modul bietet Laufzeitunterstützung für Typ-Hinweise.
Betrachten Sie die folgende Funktion
def surface_area_of_cube(edge_length: float) -> str:
return f"The surface area of the cube is {6 * edge_length ** 2}."
Die Funktion surface_area_of_cube nimmt ein Argument, das als Instanz von float erwartet wird, wie durch den Typ-Hinweis edge_length: float angezeigt. Die Funktion soll eine Instanz von str zurückgeben, wie durch den -> str Hinweis angezeigt.
Typ-Hinweise können einfache Klassen wie float oder str sein, sie können aber auch komplexer sein. Das Modul typing bietet ein Vokabular für fortgeschrittenere Typ-Hinweise.
Neue Funktionen werden häufig zum Modul typing hinzugefügt. Das Paket typing_extensions bietet Backports dieser neuen Funktionen für ältere Python-Versionen.
Siehe auch
- Typing-Cheat-Sheet
Ein kurzer Überblick über Typ-Hinweise (gehostet in der mypy-Dokumentation)
- Abschnitt „Type System Reference“ in der mypy-Dokumentation
Das Python-Typensystem ist über PEPs standardisiert, daher sollte sich dieser Referenzabschnitt grob auf die meisten Python-Typüberprüfer anwenden lassen. (Einige Teile können immer noch mypy-spezifisch sein.)
- Statische Typisierung mit Python
Typüberprüfer-agnostische Dokumentation, geschrieben von der Community, die Typensystemfunktionen, nützliche typbezogene Werkzeuge und Best Practices für die Typisierung detailliert beschreibt.
Spezifikation für das Python-Typensystem¶
Die kanonische, aktuelle Spezifikation des Python-Typensystems finden Sie unter Spezifikation für das Python-Typensystem.
Typ-Aliase¶
Ein Typ-Alias wird mit der type-Anweisung definiert, die eine Instanz von TypeAliasType erstellt. In diesem Beispiel werden Vector und list[float] von statischen Typüberprüfern gleichwertig behandelt.
type Vector = list[float]
def scale(scalar: float, vector: Vector) -> Vector:
return [scalar * num for num in vector]
# passes type checking; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
Typ-Aliase sind nützlich, um komplexe Typsignaturen zu vereinfachen. Zum Beispiel
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:
...
Die type-Anweisung ist neu in Python 3.12. Aus Gründen der Abwärtskompatibilität können Typ-Aliase auch durch einfache Zuweisung erstellt werden.
Vector = list[float]
Oder mit TypeAlias markiert, um explizit zu machen, dass es sich um einen Typ-Alias und nicht um eine normale Variablenszuweisung handelt.
from typing import TypeAlias
Vector: TypeAlias = list[float]
NewType¶
Verwenden Sie die Hilfsfunktion NewType, um eindeutige Typen zu erstellen.
from typing import NewType
UserId = NewType('UserId', int)
some_id = UserId(524313)
Der statische Typüberprüfer behandelt den neuen Typ so, als wäre er eine Unterklasse des ursprünglichen Typs. Dies ist hilfreich, um logische Fehler abzufangen.
def get_user_name(user_id: UserId) -> str:
...
# passes type checking
user_a = get_user_name(UserId(42351))
# fails type checking; an int is not a UserId
user_b = get_user_name(-1)
Sie können immer noch alle int-Operationen auf einer Variablen vom Typ UserId ausführen, aber das Ergebnis wird immer vom Typ int sein. Dies ermöglicht es Ihnen, UserId überall dort zu übergeben, wo ein int erwartet werden könnte, verhindert aber, dass Sie versehentlich eine UserId auf ungültige Weise erstellen.
# 'output' is of type 'int', not 'UserId'
output = UserId(23413) + UserId(54341)
Beachten Sie, dass diese Prüfungen nur vom statischen Typüberprüfer erzwungen werden. Zur Laufzeit macht die Anweisung Derived = NewType('Derived', Base) Derived zu einem aufrufbaren Objekt, das sofort den übergebenen Parameter zurückgibt. Das bedeutet, dass der Ausdruck Derived(some_value) keine neue Klasse erstellt und über den einer regulären Funktionsaufrufs hinaus keinen erheblichen Overhead verursacht.
Genauer gesagt ist der Ausdruck some_value is Derived(some_value) zur Laufzeit immer wahr.
Es ist ungültig, eine Unterklasse von Derived zu erstellen.
from typing import NewType
UserId = NewType('UserId', int)
# Fails at runtime and does not pass type checking
class AdminUserId(UserId): pass
Es ist jedoch möglich, ein NewType basierend auf einem „abgeleiteten“ NewType zu erstellen.
from typing import NewType
UserId = NewType('UserId', int)
ProUserId = NewType('ProUserId', UserId)
und die Typüberprüfung für ProUserId funktioniert wie erwartet.
Weitere Details finden Sie in PEP 484.
Hinweis
Denken Sie daran, dass die Verwendung eines Typ-Alias angibt, dass zwei Typen gleichwertig zueinander sind. Wenn Sie type Alias = Original verwenden, behandelt der statische Typüberprüfer Alias in allen Fällen als exakt gleichwertig zu Original. Dies ist nützlich, wenn Sie komplexe Typsignaturen vereinfachen möchten.
Im Gegensatz dazu erklärt NewType einen Typ als Untertyp eines anderen. Wenn Sie Derived = NewType('Derived', Original) verwenden, behandelt der statische Typüberprüfer Derived als Unterklasse von Original, was bedeutet, dass ein Wert vom Typ Original nicht an Stellen verwendet werden kann, an denen ein Wert vom Typ Derived erwartet wird. Dies ist nützlich, wenn Sie logische Fehler mit minimalen Laufzeitkosten verhindern möchten.
Hinzugefügt in Version 3.5.2.
Geändert in Version 3.10: NewType ist jetzt eine Klasse und keine Funktion mehr. Daher gibt es beim Aufruf von NewType einen zusätzlichen Laufzeitaufwand im Vergleich zu einer regulären Funktion.
Geändert in Version 3.11: Die Leistung beim Aufruf von NewType wurde auf das Niveau von Python 3.9 zurückgesetzt.
Annotation von aufrufbaren Objekten¶
Funktionen – oder andere aufrufbare Objekte – können mit collections.abc.Callable oder dem veralteten typing.Callable annotiert werden. Callable[[int], str] bezeichnet eine Funktion, die einen einzelnen Parameter vom Typ int nimmt und einen str zurückgibt.
Zum Beispiel
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
Die Abonnement-Syntax muss immer mit genau zwei Werten verwendet werden: der Argumentliste und dem Rückgabetyp. Die Argumentliste muss eine Liste von Typen, ein ParamSpec, Concatenate oder ein Ellipse (...) sein. Der Rückgabetyp muss ein einzelner Typ sein.
Wenn eine literale Ellipse ... als Argumentliste angegeben wird, bedeutet dies, dass ein aufrufbares Objekt mit beliebiger Parameterliste akzeptabel wäre.
def concat(x: str, y: str) -> str:
return x + y
x: Callable[..., str]
x = str # OK
x = concat # Also OK
Callable kann keine komplexen Signaturen ausdrücken, wie z. B. Funktionen, die eine variable Anzahl von Argumenten akzeptieren, überladene Funktionen oder Funktionen mit nur Schlüsselwortparametern. Diese Signaturen können jedoch durch Definition einer Protocol-Klasse mit einer __call__()-Methode ausgedrückt werden.
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
Aufrufbare Objekte, die andere aufrufbare Objekte als Argumente akzeptieren, können mit ParamSpec angeben, dass ihre Parametertypen voneinander abhängig sind. Wenn dieses aufrufbare Objekt zusätzliche Argumente hinzufügt oder entfernt, kann der Concatenate-Operator verwendet werden. Sie haben die Form Callable[ParamSpecVariable, ReturnType] bzw. Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType].
Geändert in Version 3.10: Callable unterstützt jetzt ParamSpec und Concatenate. Weitere Details finden Sie in PEP 612.
Siehe auch
Die Dokumentation für ParamSpec und Concatenate enthält Beispiele für die Verwendung in Callable.
Generics¶
Da Typinformationen über Objekte, die in Containern gespeichert sind, nicht generisch statisch abgeleitet werden können, unterstützen viele Containerklassen in der Standardbibliothek die Abonnementfunktion, um die erwarteten Typen von Containerelementen anzugeben.
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: ...
Generische Funktionen und Klassen können durch Verwendung der Typ-Parameter-Syntax parametrisiert werden.
from collections.abc import Sequence
def first[T](l: Sequence[T]) -> T: # Function is generic over the TypeVar "T"
return l[0]
Oder durch direkte Verwendung der TypeVar-Fabrik.
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]
Geändert in Version 3.12: Syntaktische Unterstützung für Generics ist neu in Python 3.12.
Annotation von Tupeln¶
Für die meisten Container in Python geht das Typsystem davon aus, dass alle Elemente im Container vom selben Typ sind. Zum Beispiel
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 akzeptiert nur ein Typargument, sodass ein Typüberprüfer einen Fehler bei der y-Zuweisung oben melden würde. Ebenso akzeptiert Mapping nur zwei Typargumente: Das erste gibt den Typ der Schlüssel und das zweite den Typ der Werte an.
Im Gegensatz zu den meisten anderen Python-Containern ist es in idiomatischem Python-Code jedoch üblich, dass Tupel Elemente enthalten, die nicht alle vom selben Typ sind. Aus diesem Grund werden Tupel in Pythons Typsystem speziell behandelt. tuple akzeptiert beliebig viele Typargumente.
# 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)
Um ein Tupel zu bezeichnen, das beliebige Länge haben kann und in dem alle Elemente vom Typ T sind, verwenden Sie die literale Ellipse ...: tuple[T, ...]. Um ein leeres Tupel zu bezeichnen, verwenden Sie tuple[()]. Die Verwendung von tuple allein als Annotation ist äquivalent zur Verwendung von 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 = ()
Der Typ von Klassenobjekten¶
Eine Variable, die mit C annotiert ist, kann einen Wert vom Typ C akzeptieren. Im Gegensatz dazu kann eine Variable, die mit type[C] (oder dem veralteten typing.Type[C]) annotiert ist, Werte akzeptieren, die selbst Klassen sind – insbesondere akzeptiert sie das Klassenobjekt von C. Zum Beispiel
a = 3 # Has type ``int``
b = int # Has type ``type[int]``
c = type(a) # Also has type ``type[int]``
Beachten Sie, dass type[C] kovariant ist.
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]``
Die einzig legalen Parameter für type sind Klassen, Any, Typ-Variablen und Vereinigungen aus diesen Typen. Zum Beispiel
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] ist äquivalent zu type, der Wurzel der Python-Hierarchie für Metaklassen.
Annotation von Generatoren und Coroutinen¶
Ein Generator kann mit dem generischen Typ Generator[YieldType, SendType, ReturnType] annotiert werden. Zum Beispiel
def echo_round() -> Generator[int, float, str]:
sent = yield 0
while sent >= 0:
sent = yield round(sent)
return 'Done'
Beachten Sie, dass der SendType von Generator, im Gegensatz zu vielen anderen generischen Klassen in der Standardbibliothek, kontravariant und nicht kovariant oder invariant ist.
Die Parameter SendType und ReturnType haben standardmäßig den Wert None.
def infinite_stream(start: int) -> Generator[int]:
while True:
yield start
start += 1
Es ist auch möglich, diese Typen explizit festzulegen.
def infinite_stream(start: int) -> Generator[int, None, None]:
while True:
yield start
start += 1
Einfache Generatoren, die nur Werte erzeugen, können auch so annotiert werden, dass sie einen Rückgabetyp von entweder Iterable[YieldType] oder Iterator[YieldType] haben.
def infinite_stream(start: int) -> Iterator[int]:
while True:
yield start
start += 1
Asynchrone Generatoren werden auf ähnliche Weise behandelt, erwarten aber keinen ReturnType-Typargument (AsyncGenerator[YieldType, SendType]). Das Argument SendType hat standardmäßig den Wert None, sodass die folgenden Definitionen äquivalent sind.
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)
Wie im synchronen Fall sind auch AsyncIterable[YieldType] und AsyncIterator[YieldType] verfügbar.
async def infinite_stream(start: int) -> AsyncIterator[int]:
while True:
yield start
start = await increment(start)
Coroutinen können mit Coroutine[YieldType, SendType, ReturnType] annotiert werden. Die generischen Argumente entsprechen denen von Generator, zum Beispiel.
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
Benutzerdefinierte generische Typen¶
Eine benutzerdefinierte Klasse kann als generische Klasse definiert werden.
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)
Diese Syntax zeigt an, dass die Klasse LoggedVar um eine einzelne Typ-Variable T parametrisiert ist. Dies macht T auch als Typ innerhalb des Klassenkörpers gültig.
Generische Klassen erben implizit von Generic. Für die Kompatibilität mit Python 3.11 und niedriger ist es auch möglich, explizit von Generic zu erben, um eine generische Klasse anzugeben.
from typing import TypeVar, Generic
T = TypeVar('T')
class LoggedVar(Generic[T]):
...
Generische Klassen haben Methoden __class_getitem__(), was bedeutet, dass sie zur Laufzeit parametrisiert werden können (z. B. LoggedVar[int] unten).
from collections.abc import Iterable
def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
for var in vars:
var.set(0)
Ein generischer Typ kann beliebig viele Typvariablen haben. Alle Arten von TypeVar sind als Parameter für einen generischen Typ zulässig.
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]):
...
Jede Typvariablen-Argument für Generic muss unterschiedlich sein. Dies ist daher ungültig.
from typing import TypeVar, Generic
...
class Pair[M, M]: # SyntaxError
...
T = TypeVar('T')
class Pair(Generic[T, T]): # INVALID
...
Generische Klassen können auch von anderen Klassen erben.
from collections.abc import Sized
class LinkedList[T](Sized):
...
Beim Erben von generischen Klassen können einige Typ-Parameter festgelegt werden.
from collections.abc import Mapping
class MyDict[T](Mapping[str, T]):
...
In diesem Fall hat MyDict einen einzelnen Parameter, T.
Die Verwendung einer generischen Klasse ohne Angabe von Typ-Parametern geht davon aus, dass für jede Position Any verwendet wird. Im folgenden Beispiel ist MyIterable nicht generisch, erbt aber implizit von Iterable[Any].
from collections.abc import Iterable
class MyIterable(Iterable): # Same as Iterable[Any]
...
Benutzerdefinierte generische Typ-Aliase werden ebenfalls unterstützt. Beispiele.
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)
Aus Kompatibilitätsgründen können generische Typ-Aliase auch durch eine einfache Zuweisung erstellt werden.
from collections.abc import Iterable
from typing import TypeVar
S = TypeVar("S")
Response = Iterable[S] | int
Geändert in Version 3.7: Generic hat keine benutzerdefinierte Metaklasse mehr.
Geändert in Version 3.12: Syntaktische Unterstützung für Generics und Typ-Aliase ist neu in Version 3.12. Zuvor mussten generische Klassen explizit von Generic erben oder eine Typ-Variable in einer ihrer Basisklassen enthalten.
Benutzerdefinierte Generics für Parameterausdrücke werden ebenfalls über Parameterspezifikationsvariablen in der Form [**P] unterstützt. Das Verhalten ist konsistent mit den oben beschriebenen Typvariablen, da Parameterspezifikationsvariablen vom Modul typing als spezialisierte Typvariable behandelt werden. Die einzige Ausnahme ist, dass eine Liste von Typen verwendet werden kann, um ein ParamSpec zu ersetzen.
>>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec
...
>>> Z[int, [dict, float]]
__main__.Z[int, [dict, float]]
Klassen, die über ein ParamSpec generisch sind, können auch durch explizite Vererbung von Generic erstellt werden. In diesem Fall wird ** nicht verwendet.
from typing import ParamSpec, Generic
P = ParamSpec('P')
class Z(Generic[P]):
...
Ein weiterer Unterschied zwischen TypeVar und ParamSpec ist, dass ein Generic mit nur einer Parameterspezifikationsvariablen Parameterlisten in den Formen X[[Type1, Type2, ...]] und auch X[Type1, Type2, ...] aus ästhetischen Gründen akzeptiert. Intern wird Letzteres in das Erstere umgewandelt, sodass die folgenden Ausdrücke äquivalent sind.
>>> class X[**P]: ...
...
>>> X[int, str]
__main__.X[[int, str]]
>>> X[[int, str]]
__main__.X[[int, str]]
Beachten Sie, dass Generics mit ParamSpec in einigen Fällen möglicherweise keine korrekten __parameters__ nach der Ersetzung haben, da sie hauptsächlich für die statische Typüberprüfung gedacht sind.
Geändert in Version 3.10: Generic kann jetzt über Parameterausdrücke parametrisiert werden. Weitere Details finden Sie in ParamSpec und PEP 612.
Eine benutzerdefinierte generische Klasse kann ABCs als Basisklassen ohne Metaklassenkonflikt haben. Generische Metaklassen werden nicht unterstützt. Das Ergebnis der Parametrisierung von Generics wird zwischengespeichert, und die meisten Typen im Modul typing sind hashable und auf Gleichheit vergleichbar.
Der Typ Any¶
Eine spezielle Art von Typ ist Any. Ein statischer Typüberprüfer behandelt jeden Typ als kompatibel mit Any und Any als kompatibel mit jedem Typ.
Das bedeutet, dass es möglich ist, jede Operation oder jeden Methodenaufruf auf einem Wert vom Typ Any durchzuführen und ihn einer beliebigen Variablen zuzuweisen.
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()
...
Beachten Sie, dass keine Typüberprüfung durchgeführt wird, wenn ein Wert vom Typ Any einem präziseren Typ zugewiesen wird. Zum Beispiel hat der statische Typüberprüfer keinen Fehler gemeldet, als a s zugewiesen wurde, obwohl s als Typ str deklariert war und zur Laufzeit einen Wert vom Typ int erhält!
Darüber hinaus werden alle Funktionen ohne Rückgabetyp oder Parametertypen standardmäßig auf Any gesetzt.
def legacy_parser(text):
...
return data
# A static type checker will treat the above
# as having the same signature as:
def legacy_parser(text: Any) -> Any:
...
return data
Dieses Verhalten ermöglicht es Any als Notausgang zu verwenden, wenn Sie dynamisch und statisch typisierten Code mischen müssen.
Vergleichen Sie das Verhalten von Any mit dem von object. Ähnlich wie Any ist jeder Typ eine Unterklasse von object. Im Gegensatz zu Any ist das Umgekehrte jedoch nicht der Fall: object ist keine Unterklasse jedes anderen Typs.
Das bedeutet, wenn der Typ eines Wertes object ist, lehnt ein Typüberprüfer fast alle Operationen darauf ab, und die Zuweisung an eine Variable (oder die Verwendung als Rückgabewert) eines spezialisierteren Typs ist ein Typfehler. Zum Beispiel.
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")
Verwenden Sie object, um anzugeben, dass ein Wert auf typsichere Weise jeder Typ sein könnte. Verwenden Sie Any, um anzugeben, dass ein Wert dynamisch typisiert ist.
Nominale vs. strukturelle Subtyps¶
Ursprünglich definierte PEP 484 das statische Python-Typsystem als Verwendung von nominalem Subtyping. Das bedeutet, dass eine Klasse A dort zulässig ist, wo eine Klasse B erwartet wird, wenn und nur wenn A eine Unterklasse von B ist.
Diese Anforderung galt zuvor auch für abstrakte Basisklassen, wie z. B. Iterable. Das Problem bei diesem Ansatz war, dass eine Klasse explizit markiert werden musste, um sie zu unterstützen, was unpythonisch ist und nicht dem entspricht, was man normalerweise im idiomatischen dynamisch typisierten Python-Code tun würde. Zum Beispiel entspricht dies 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öst dieses Problem, indem es Benutzern ermöglicht, den obigen Code ohne explizite Basisklassen in der Klassendefinition zu schreiben, sodass Bucket von statischen Typüberprüfern implizit sowohl als Untertyp von Sized als auch von Iterable[int] betrachtet wird. Dies wird als strukturelles Subtyping (oder statisches Duck-Typing) bezeichnet.
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
Darüber hinaus kann ein Benutzer durch Unterklassifizierung einer speziellen Klasse Protocol neue benutzerdefinierte Protokolle definieren, um das strukturelle Subtyping vollständig zu nutzen (siehe Beispiele unten).
Modulinhalt¶
Das Modul typing definiert die folgenden Klassen, Funktionen und Dekoratoren.
Spezielle Typenprimitive¶
Spezielle Typen¶
Diese können als Typen in Annotationen verwendet werden. Sie unterstützen kein Abonnement mit [].
- typing.Any¶
Spezieller Typ, der einen unbeschränkten Typ angibt.
Geändert in Version 3.11:
Anykann jetzt als Basisklasse verwendet werden. Dies kann nützlich sein, um Typenprüfungsfehler bei Klassen zu vermeiden, die überall Duck-Typing unterstützen oder sehr dynamisch sind.
- typing.AnyStr¶
Eine beschränkte Tyavariable.
Definition
AnyStr = TypeVar('AnyStr', str, bytes)
AnyStrist für Funktionen gedacht, diestroderbytesArgumente akzeptieren können, aber die beiden nicht mischen dürfen.Zum Beispiel
def concat(a: AnyStr, b: AnyStr) -> AnyStr: return a + b concat("foo", "bar") # OK, output has type 'str' concat(b"foo", b"bar") # OK, output has type 'bytes' concat("foo", b"bar") # Error, cannot mix str and bytes
Beachten Sie, dass
AnyStrtrotz seines Namens nichts mit demAnyTyp zu tun hat, noch bedeutet es „beliebige Zeichenkette“. Insbesondere sindAnyStrundstr | bytesunterschiedlich und haben unterschiedliche Anwendungsfälle.# Invalid use of AnyStr: # The type variable is used only once in the function signature, # so cannot be "solved" by the type checker def greet_bad(cond: bool) -> AnyStr: return "hi there!" if cond else b"greetings!" # The better way of annotating this function: def greet_proper(cond: bool) -> str | bytes: return "hi there!" if cond else b"greetings!"
Veraltet seit Version 3.13, wird in Version 3.18 entfernt: Veraltet zugunsten der neuen Typparametersyntax. Verwenden Sie
class A[T: (str, bytes)]: ...anstelle des Imports vonAnyStr. Weitere Details finden Sie in PEP 695.In Python 3.16 wird
AnyStraustyping.__all__entfernt, und Laufzeit-Deprecation-Warnungen werden ausgegeben, wenn darauf zugegriffen oder es austypingimportiert wird.AnyStrwird austypingin Python 3.18 entfernt.
- typing.LiteralString¶
Spezieller Typ, der nur literale Zeichenketten enthält.
Jede Zeichenkettenliterale ist mit
LiteralStringkompatibel, ebenso wie eine andereLiteralString. Ein als nurstrtypisiertes Objekt ist dies jedoch nicht. Eine durch die Zusammensetzung vonLiteralStringtypisierten Objekten erstellte Zeichenkette ist ebenfalls alsLiteralStringzulässig.Beispiel
def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: run_query("SELECT * FROM students") # OK run_query(literal_string) # OK run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" )
LiteralStringist nützlich für sensible APIs, bei denen willkürlich vom Benutzer generierte Zeichenketten Probleme verursachen könnten. Die beiden oben genannten Fälle, die Typenprüfungsfehler erzeugen, könnten beispielsweise anfällig für einen SQL-Injection-Angriff sein.Weitere Details finden Sie in PEP 675.
Hinzugefügt in Version 3.11.
- typing.Never¶
- typing.NoReturn¶
NeverundNoReturnrepräsentieren den bottom type, einen Typ, der keine Elemente hat.Sie können verwendet werden, um anzuzeigen, dass eine Funktion nie zurückkehrt, wie z. B.
sys.exit()from typing import Never # or NoReturn def stop() -> Never: raise RuntimeError('no way')
Oder um eine Funktion zu definieren, die niemals aufgerufen werden sollte, da es keine gültigen Argumente gibt, wie z. B.
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)
NeverundNoReturnhaben die gleiche Bedeutung im Typsystem und statische Typenprüfer behandeln beide gleichwertig.Hinzugefügt in Version 3.6.2:
NoReturnhinzugefügt.Hinzugefügt in Version 3.11:
Neverhinzugefügt.
- typing.Self¶
Spezieller Typ zur Darstellung der aktuell umschließenden Klasse.
Zum Beispiel
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"
Diese Annotation ist semantisch äquivalent zu folgendem, wenn auch auf prägnantere Weise
from typing import TypeVar Self = TypeVar("Self", bound="Foo") class Foo: def return_self(self: Self) -> Self: ... return self
Im Allgemeinen sollten Sie, wenn etwas
selfzurückgibt, wie in den obigen Beispielen,Selfals Rückgabeannotation verwenden. WennFoo.return_selfals Rückgabe von"Foo"annotiert wäre, würde der Typenprüfer das vonSubclassOfFoo.return_selfzurückgegebene Objekt als vom TypFoound nicht alsSubclassOfFooableiten.Weitere gängige Anwendungsfälle sind
classmethods, die als alternative Konstruktoren verwendet werden und Instanzen descls-Parameters zurückgeben.Annotation einer
__enter__()-Methode, die self zurückgibt.
Sie sollten
Selfnicht als Rückgabeannotation verwenden, wenn die Methode nicht garantiert eine Instanz einer Unterklasse zurückgibt, wenn die Klasse unterklassenbildet wird.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()
Weitere Details finden Sie in PEP 673.
Hinzugefügt in Version 3.11.
- typing.TypeAlias¶
Spezielle Annotation zur expliziten Deklaration eines Typen-Alias.
Zum Beispiel
from typing import TypeAlias Factors: TypeAlias = list[int]
TypeAliasist besonders nützlich in älteren Python-Versionen zur Annotation von Aliasen, die Vorwärtsreferenzen verwenden, da es für Typenprüfer schwierig sein kann, diese von normalen Variablendeklarationen zu unterscheiden.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: ...
Weitere Details finden Sie in PEP 613.
Hinzugefügt in Version 3.10.
Veraltet seit Version 3.12:
TypeAliasist zugunsten dertype-Anweisung veraltet, die Instanzen vonTypeAliasTypeerstellt und die nativ Vorwärtsreferenzen unterstützt. Beachten Sie, dassTypeAliasundTypeAliasTypezwar ähnliche Zwecke erfüllen und ähnliche Namen haben, aber unterschiedlich sind und letzteres nicht der Typ des ersteren ist. Eine Entfernung vonTypeAliasist derzeit nicht geplant, aber Benutzer werden ermutigt, auftype-Anweisungen umzusteigen.
Spezielle Formen¶
Diese können als Typen in Annotationen verwendet werden. Sie unterstützen alle die Subskription mit [], haben aber jeweils eine eindeutige Syntax.
- class typing.Union¶
Vereinigungstyp;
Union[X, Y]ist äquivalent zuX | Yund bedeutet entweder X oder Y.Um eine Vereinigung zu definieren, verwenden Sie z. B.
Union[int, str]oder die Kurzformint | str. Die Verwendung dieser Kurzform wird empfohlen. DetailsDie Argumente müssen Typen sein und es muss mindestens ein Argument geben.
Vereinigungen von Vereinigungen werden abgeflacht, z. B.
Union[Union[int, str], float] == Union[int, str, float]
Dies gilt jedoch nicht für Vereinigungen, auf die über einen Typen-Alias verwiesen wird, um die Auswertung des zugrunde liegenden
TypeAliasTypezu vermeiden.type A = Union[int, str] Union[A, float] != Union[int, str, float]
Vereinigungen mit einem einzigen Argument verschwinden, z. B.
Union[int] == int # The constructor actually returns int
Redundante Argumente werden übersprungen, z. B.
Union[int, str, int] == Union[int, str] == int | str
Beim Vergleichen von Vereinigungen wird die Argumentreihenfolge ignoriert, z. B.
Union[int, str] == Union[str, int]
Sie können eine
Unionnicht unterklassen oder instanziieren.Sie können nicht
Union[X][Y]schreiben.
Geändert in Version 3.7: Explizite Unterklassen werden zur Laufzeit nicht mehr aus Vereinigungen entfernt.
Geändert in Version 3.10: Vereinigungen können jetzt als
X | Ygeschrieben werden. Siehe Vereinigungstyp-Ausdrücke.Geändert in Version 3.14:
types.UnionTypeist jetzt ein Alias fürUnion, und sowohlUnion[int, str]als auchint | strerstellen Instanzen derselben Klasse. Um zu prüfen, ob ein Objekt eineUnionzur Laufzeit ist, verwenden Sieisinstance(obj, Union). Für Kompatibilität mit früheren Python-Versionen verwenden Sieget_origin(obj) is typing.Union or get_origin(obj) is types.UnionType.
- typing.Optional¶
Optional[X]ist äquivalent zuX | None(oderUnion[X, None]).Beachten Sie, dass dies nicht dasselbe Konzept ist wie ein optionales Argument, das ein solches mit einem Standardwert ist. Ein optionales Argument mit einem Standardwert benötigt nicht unbedingt den
Optional-Qualifizierer für seine Typannotation, nur weil es optional ist. Zum Beispieldef foo(arg: int = 0) -> None: ...
Andererseits, wenn ein expliziter Wert von
Noneerlaubt ist, ist die Verwendung vonOptionalangemessen, unabhängig davon, ob das Argument optional ist oder nicht. Zum Beispieldef foo(arg: Optional[int] = None) -> None: ...
Geändert in Version 3.10: Optional kann jetzt als
X | Nonegeschrieben werden. Siehe Vereinigungstyp-Ausdrücke.
- typing.Concatenate¶
Spezielle Form zur Annotation von höherrangigen Funktionen.
Concatenatekann in Verbindung mit Callable undParamSpecverwendet werden, um einen höherrangigen aufrufbaren Typ zu annotieren, der Parameter eines anderen aufrufbaren Typs hinzufügt, entfernt oder transformiert. Die Verwendung erfolgt in der FormConcatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable].Concatenateist derzeit nur gültig, wenn es als erstes Argument von Callable verwendet wird. Der letzte Parameter vonConcatenatemuss einParamSpecoder Ellipse (...) sein.Um beispielsweise einen Dekorator
with_lockzu annotieren, der einethreading.Lockfür die dekorierte Funktion bereitstellt, kannConcatenateverwendet werden, um anzuzeigen, dasswith_lockeinen aufrufbaren Typ erwartet, der eineLockals erstes Argument nimmt und einen aufrufbaren Typ mit einer anderen Signatur zurückgibt. In diesem Fall gibtParamSpecan, dass die Parametertypen des zurückgegebenen aufrufbaren Typs von den Parametertypen des übergebenen aufrufbaren Typs abhängen.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])
Hinzugefügt in Version 3.10.
Siehe auch
PEP 612 – Parameter Specification Variables (die PEP, die
ParamSpecundConcatenateeingeführt hat)
- typing.Literal¶
Spezielle Typsignatur zur Definition von „literalen Typen“.
Literalkann verwendet werden, um Typenprüfern anzuzeigen, dass das annotierte Objekt einen Wert hat, der einem der bereitgestellten Literale entspricht.Zum Beispiel
def validate_simple(data: Any) -> Literal[True]: # always returns True ... type Mode = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: Mode) -> str: ... open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checker
Literal[...]kann nicht unterklassen werden. Zur Laufzeit ist jeder beliebige Wert als Typargument fürLiteral[...]zulässig, Typenprüfer können jedoch Einschränkungen auferlegen. Weitere Details zu literalen Typen finden Sie in PEP 586.Zusätzliche Details
Die Argumente müssen literale Werte sein und es muss mindestens eines geben.
Verschachtelte
Literal-Typen werden abgeflacht, z. B.assert Literal[Literal[1, 2], 3] == Literal[1, 2, 3]
Dies gilt jedoch nicht für
Literal-Typen, auf die über einen Typen-Alias verwiesen wird, um die Auswertung des zugrunde liegendenTypeAliasTypezu vermeiden.type A = Literal[1, 2] assert Literal[A, 3] != Literal[1, 2, 3]
Redundante Argumente werden übersprungen, z. B.
assert Literal[1, 2, 1] == Literal[1, 2]
Beim Vergleichen von Literalen wird die Argumentreihenfolge ignoriert, z. B.
assert Literal[1, 2] == Literal[2, 1]
Sie können eine
Literalnicht unterklassen oder instanziieren.Sie können nicht
Literal[X][Y]schreiben.
Hinzugefügt in Version 3.8.
- typing.ClassVar¶
Spezielle Typkonstruktion zur Markierung von Klassenvariablen.
Wie in PEP 526 eingeführt, kennzeichnet eine Variablenannotation, die in ClassVar verpackt ist, dass ein bestimmtes Attribut als Klassenvariable verwendet werden soll und nicht auf Instanzen dieser Klasse gesetzt werden sollte. Verwendung
class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable
ClassVarakzeptiert nur Typen und kann nicht weiter abonniert werden.ClassVarist selbst keine Klasse und sollte nicht mitisinstance()oderissubclass()verwendet werden.ClassVarändert das Laufzeitverhalten von Python nicht, kann aber von Drittanbieter-Typenprüfern verwendet werden. Zum Beispiel könnte ein Typenprüfer den folgenden Code als Fehler kennzeichnen.enterprise_d = Starship(3000) enterprise_d.stats = {} # Error, setting class variable on instance Starship.stats = {} # This is OK
Hinzugefügt in Version 3.5.3.
- typing.Final¶
Spezielle Typsignatur zur Kennzeichnung finaler Namen für Typenprüfer.
Finale Namen können in keinem Gültigkeitsbereich neu zugewiesen werden. In Klassenbereichen deklarierte finale Namen können in Unterklassen nicht überschrieben werden.
Zum Beispiel
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
Es gibt keine Laufzeitüberprüfung dieser Eigenschaften. Weitere Details finden Sie in PEP 591.
Hinzugefügt in Version 3.8.
- typing.Required¶
Spezielle Typsignatur zum Markieren eines Schlüssels in einem
TypedDictals erforderlich.Dies ist hauptsächlich nützlich für
total=FalseTypedDicts. Weitere Details finden Sie inTypedDictund PEP 655.Hinzugefügt in Version 3.11.
- typing.NotRequired¶
Spezielle Typsignatur zum Markieren eines Schlüssels in einem
TypedDictals potenziell fehlend.Weitere Details finden Sie in
TypedDictund PEP 655.Hinzugefügt in Version 3.11.
- typing.ReadOnly¶
Eine spezielle Typsignatur zum Markieren eines Elements eines
TypedDictals schreibgeschützt.Zum Beispiel
class Movie(TypedDict): title: ReadOnly[str] year: int def mutate_movie(m: Movie) -> None: m["year"] = 1999 # allowed m["title"] = "The Matrix" # typechecker error
Es gibt keine Laufzeitüberprüfung für diese Eigenschaft.
Weitere Details finden Sie in
TypedDictund PEP 705.Hinzugefügt in Version 3.13.
- typing.Annotated¶
Spezielle Typsignatur zur Hinzufügung von kontextspezifischen Metadaten zu einer Annotation.
Fügen Sie einer gegebenen Typisierung
TMetadatenxhinzu, indem Sie die AnnotationAnnotated[T, x]verwenden. MitAnnotatedhinzugefügte Metadaten können von statischen Analysewerkzeugen oder zur Laufzeit verwendet werden. Zur Laufzeit werden die Metadaten in einem Attribut__metadata__gespeichert.Wenn eine Bibliothek oder ein Werkzeug eine Annotation
Annotated[T, x]antrifft und keine spezielle Logik für die Metadaten hat, sollte es die Metadaten ignorieren und die Annotation einfach alsTbehandeln. Als solches kannAnnotatedfür Code nützlich sein, der Annotationen für Zwecke außerhalb des statischen Typsystems von Python verwenden möchte.Die Verwendung von
Annotated[T, x]als Annotation ermöglicht weiterhin die statische Typenprüfung vonT, da Typenprüfer die Metadatenxeinfach ignorieren. Auf diese Weise unterscheidet sichAnnotatedvom@no_type_check-Dekorator, der auch zur Hinzufügung von Annotationen außerhalb des Umfangs des Typsystems verwendet werden kann, aber die Typenprüfung für eine Funktion oder Klasse vollständig deaktiviert.Die Verantwortung für die Interpretation der Metadaten liegt bei dem Werkzeug oder der Bibliothek, die eine
Annotated-Annotation vorfindet. Ein Werkzeug oder eine Bibliothek, die einenAnnotated-Typ antrifft, kann die Metadatenelemente durchsuchen, um festzustellen, ob sie von Interesse sind (z. B. mithilfe vonisinstance()).- Annotated[<Typ>, <Metadaten>]
Hier ist ein Beispiel dafür, wie Sie
Annotatedverwenden könnten, um Metadaten zu Typannotationen hinzuzufügen, wenn Sie eine Bereichsanalyse durchführen würden.@dataclass class ValueRange: lo: int hi: int T1 = Annotated[int, ValueRange(-10, 5)] T2 = Annotated[T1, ValueRange(-20, 3)]
Das erste Argument für
Annotatedmuss ein gültiger Typ sein. Mehrere Metadatenelemente können angegeben werden, daAnnotatedvariable Argumente unterstützt. Die Reihenfolge der Metadatenelemente bleibt erhalten und ist für Gleichheitsprüfungen wichtig.@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
Es liegt am Werkzeug, das die Annotationen konsumiert, zu entscheiden, ob der Client mehrere Metadatenelemente zu einer Annotation hinzufügen darf und wie diese Annotationen zusammengeführt werden.
Verschachtelte
Annotated-Typen werden abgeflacht. Die Reihenfolge der Metadatenelemente beginnt mit der innersten Annotation.assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ int, ValueRange(3, 10), ctype("char") ]
Dies gilt jedoch nicht für
Annotated-Typen, auf die über einen Typen-Alias verwiesen wird, um die Auswertung des zugrunde liegendenTypeAliasTypezu vermeiden.type From3To10[T] = Annotated[T, ValueRange(3, 10)] assert Annotated[From3To10[int], ctype("char")] != Annotated[ int, ValueRange(3, 10), ctype("char") ]
Duplizierte Metadatenelemente werden nicht entfernt.
assert Annotated[int, ValueRange(3, 10)] != Annotated[ int, ValueRange(3, 10), ValueRange(3, 10) ]
Annotatedkann mit verschachtelten und generischen Aliasen verwendet werden.@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]
Annotatedkann nicht mit einem entpacktenTypeVarTupleverwendet werden.type Variadic[*Ts] = Annotated[*Ts, Ann1] = Annotated[T1, T2, T3, ..., Ann1] # NOT valid
wobei
T1,T2, ...TypeVarssind. Dies ist ungültig, da nur ein Typ an Annotated übergeben werden sollte.Standardmäßig entfernt
get_type_hints()die Metadaten aus Annotationen. Übergeben Sieinclude_extras=True, um die Metadaten beizubehalten.>>> 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'>}
Zur Laufzeit können die Metadaten, die einem
Annotated-Typ zugeordnet sind, über das Attribut__metadata__abgerufen werden.>>> from typing import Annotated >>> X = Annotated[int, "very", "important", "metadata"] >>> X typing.Annotated[int, 'very', 'important', 'metadata'] >>> X.__metadata__ ('very', 'important', 'metadata')
Wenn Sie den ursprünglichen Typ abrufen möchten, der von
Annotatedumschlossen wird, verwenden Sie das Attribut__origin__.>>> from typing import Annotated, get_origin >>> Password = Annotated[str, "secret"] >>> Password.__origin__ <class 'str'>
Beachten Sie, dass die Verwendung von
get_origin()Annotatedselbst zurückgibt.>>> get_origin(Password) typing.Annotated
Siehe auch
- PEP 593 – Flexible Funktions- und Variablenannotationen
Die PEP, die
Annotatedin die Standardbibliothek eingeführt hat.
Hinzugefügt in Version 3.9.
- typing.TypeIs¶
Spezielle Typsignatur zum Markieren benutzerdefinierter Typprädikatfunktionen.
TypeIskann verwendet werden, um den Rückgabetyp einer benutzerdefinierten Typprädikatfunktion zu annotieren.TypeIsakzeptiert nur ein einzelnes Typargument. Zur Laufzeit sollten Funktionen, die auf diese Weise markiert sind, einen booleschen Wert zurückgeben und mindestens ein Positionsargument akzeptieren.TypeIszielt darauf ab, *Typ-Narrowing* zu unterstützen – eine Technik, die von statischen Typenprüfern verwendet wird, um einen präziseren Typ eines Ausdrucks innerhalb des Programmablaufs zu ermitteln. Normalerweise wird Typ-Narrowing durch die Analyse des bedingten Programmablaufs und die Anwendung des Narrowings auf einen Codeblock durchgeführt. Der bedingte Ausdruck wird hier manchmal als „Typprädikat“ bezeichnet.def is_str(val: str | float): # "isinstance" type predicate if isinstance(val, str): # Type of ``val`` is narrowed to ``str`` ... else: # Else, type of ``val`` is narrowed to ``float``. ...
Manchmal ist es praktisch, eine benutzerdefinierte boolesche Funktion als Typprädikat zu verwenden. Eine solche Funktion sollte
TypeIs[...]oderTypeGuardals Rückgabetyp verwenden, um statische Typenprüfer auf diese Absicht aufmerksam zu machen.TypeIshat normalerweise ein intuitiveres Verhalten alsTypeGuard, kann aber nicht verwendet werden, wenn die Eingabe- und Ausgabetypen inkompatibel sind (z. B.list[object]zulist[int]) oder wenn die Funktion nichtTruefür alle Instanzen des verengten Typs zurückgibt.Die Verwendung von
-> TypeIs[NarrowedType]teilt dem statischen Typenprüfer mit, dass für eine gegebene FunktionDer Rückgabewert ist ein boolescher Wert.
Wenn der Rückgabewert
Trueist, ist der Typ seines Arguments die Schnittmenge des ursprünglichen Typs des Arguments undNarrowedType.Wenn der Rückgabewert
Falseist, wird der Typ seines Arguments auf den Ausschluss vonNarrowedTypeverengt.
Zum Beispiel
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)
Der Typ innerhalb von
TypeIsmuss mit dem Typ des Funktionsarguments übereinstimmen; falls dies nicht der Fall ist, lösen statische Typenprüfer einen Fehler aus. Eine falsch geschriebeneTypeIs-Funktion kann zu inkonsistentem Verhalten im Typsystem führen; es liegt in der Verantwortung des Benutzers, solche Funktionen typsicher zu schreiben.Wenn eine
TypeIs-Funktion eine Klassen- oder Instanzmethode ist, dann bezieht sich der Typ inTypeIsauf den Typ des zweiten Parameters (nachclsoderself).Kurz gesagt, die Form
def foo(arg: TypeA) -> TypeIs[TypeB]: ...bedeutet, dass, wennfoo(arg)Truezurückgibt,argeine Instanz vonTypeBist, und wenn esFalsezurückgibt, ist es keine Instanz vonTypeB.TypeIsfunktioniert auch mit Tyvariablen. Weitere Informationen finden Sie in PEP 742 (Narrowing types withTypeIs).Hinzugefügt in Version 3.13.
- typing.TypeGuard¶
Spezielle Typsignatur zum Markieren benutzerdefinierter Typprädikatfunktionen.
Typ-Prädikatfunktionen sind benutzerdefinierte Funktionen, die zurückgeben, ob ihr Argument eine Instanz eines bestimmten Typs ist.
TypeGuardfunktioniert ähnlich wieTypeIs, hat aber subtil andere Auswirkungen auf das Verhalten der Typüberprüfung (siehe unten).Die Verwendung von
-> TypeGuardteilt dem statischen Typenprüfer mit, dass für eine gegebene FunktionDer Rückgabewert ist ein boolescher Wert.
Wenn der Rückgabewert
Trueist, hat der Typ seines Arguments den Typ innerhalb vonTypeGuard.
TypeGuardfunktioniert auch mit Tyvariablen. Weitere Details finden Sie in PEP 647.Zum Beispiel
def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Determines whether all objects in the list are strings''' return all(isinstance(x, str) for x in val) def func1(val: list[object]): if is_str_list(val): # Type of ``val`` is narrowed to ``list[str]``. print(" ".join(val)) else: # Type of ``val`` remains as ``list[object]``. print("Not a list of strings!")
TypeIsundTypeGuardunterscheiden sich in folgenden Punkten:TypeIsverlangt, dass der verengte Typ eine Unterart des Eingabetyps ist, währendTypeGuarddies nicht tut. Der Hauptgrund dafür ist, dass Dinge wie das Verengen vonlist[object]zulist[str]ermöglicht werden, obwohl letzteres keine Unterart ersteren ist, dalistinvariant ist.Wenn eine
TypeGuard-FunktionTruezurückgibt, verengen Typenprüfer den Typ der Variablen auf exakt denTypeGuard-Typ. Wenn eineTypeIs-FunktionTruezurückgibt, können Typenprüfer einen präziseren Typ ableiten, indem sie den zuvor bekannten Typ der Variablen mit demTypeIs-Typ kombinieren. (Technisch gesehen wird dies als Schnittmengentyp bezeichnet.)Wenn eine
TypeGuard-FunktionFalsezurückgibt, können Typenprüfer den Typ der Variablen überhaupt nicht verengen. Wenn eineTypeIs-FunktionFalsezurückgibt, können Typenprüfer den Typ der Variablen verengen, um denTypeIs-Typ auszuschließen.
Hinzugefügt in Version 3.10.
- typing.Unpack¶
Typing-Operator, um ein Objekt konzeptionell als "entpackt" zu markieren.
Zum Beispiel ist die Verwendung des Entpackungsoperators
*auf ein Typtupel äquivalent zur Verwendung vonUnpack, um das Typtupel als entpackt zu markieren.Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Effectively does: tup: tuple[Unpack[Ts]]
Tatsächlich kann
Unpackim Kontext vontyping.TypeVarTupleundbuiltins.tuple-Typen austauschbar mit*verwendet werden. Möglicherweise sehen SieUnpackexplizit in älteren Python-Versionen verwendet, wo*an bestimmten Stellen nicht verwendet werden konnte.# In older versions of Python, TypeVarTuple and Unpack # are located in the `typing_extensions` backports package. from typing_extensions import TypeVarTuple, Unpack Ts = TypeVarTuple('Ts') tup: tuple[*Ts] # Syntax error on Python <= 3.10! tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible
Unpackkann auch zusammen mittyping.TypedDictverwendet werden, um**kwargsin einer Funktionssignatur zu typisieren.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]): ...
Weitere Details zur Verwendung von
Unpackfür die Typisierung von**kwargsfinden Sie in PEP 692.Hinzugefügt in Version 3.11.
Erstellung von generischen Typen und Typ-Aliassen¶
Die folgenden Klassen sollten nicht direkt als Annotationen verwendet werden. Ihr beabsichtigter Zweck ist es, Bausteine für die Erstellung von generischen Typen und Typ-Aliassen zu sein.
Diese Objekte können über spezielle Syntax (Typparameterlisten und die type-Anweisung) erstellt werden. Zur Kompatibilität mit Python 3.11 und früher können sie auch ohne die dedizierte Syntax erstellt werden, wie unten dokumentiert.
- class typing.Generic¶
Abstrakte Basisklasse für generische Typen.
Ein generischer Typ wird typischerweise durch Hinzufügen einer Liste von Typparametern nach dem Klassennamen deklariert.
class Mapping[KT, VT]: def __getitem__(self, key: KT) -> VT: ... # Etc.
Eine solche Klasse erbt implizit von
Generic. Die Laufzeitsemantik dieser Syntax wird in der Sprachreferenz diskutiert.Diese Klasse kann dann wie folgt verwendet werden:
def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y: try: return mapping[key] except KeyError: return default
Hier geben die Klammern nach dem Funktionsnamen eine generische Funktion an.
Aus Gründen der Abwärtskompatibilität können generische Klassen auch durch explizites Erben von
Genericdeklariert werden. In diesem Fall müssen die Typparameter separat deklariert werden: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)¶
Typparameter.
Der bevorzugte Weg zur Erstellung eines Typparameters ist über die dedizierte Syntax für generische Funktionen, generische Klassen und generische Typ-Aliasse.
class Sequence[T]: # T is a TypeVar ...
Diese Syntax kann auch verwendet werden, um gebundene und eingeschränkte Typparameter zu erstellen:
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 ...
Wenn gewünscht, können wiederverwendbare Typparameter jedoch auch manuell konstruiert werden, wie folgt:
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
Typparameter existieren primär zum Nutzen statischer Typenprüfer. Sie dienen als Parameter für generische Typen sowie für Definitionen von generischen Funktionen und Typ-Aliassen. Weitere Informationen zu generischen Typen finden Sie unter
Generic. Generische Funktionen funktionieren wie folgt:def repeat[T](x: T, n: int) -> Sequence[T]: """Return a list containing n references to x.""" return [x]*n def print_capitalized[S: str](x: S) -> S: """Print x capitalized, and return x.""" print(x.capitalize()) return x def concatenate[A: (str, bytes)](x: A, y: A) -> A: """Add two strings or bytes objects together.""" return x + y
Beachten Sie, dass Typparameter *gebunden*, *eingeschränkt* oder weder noch sein können, aber nicht sowohl gebunden als auch eingeschränkt.
Die Varianz von Typparametern wird von Typenprüfern abgeleitet, wenn sie über die Typparametersyntax erstellt werden oder wenn
infer_variance=Trueübergeben wird. Manuell erstellte Typparameter können explizit als kovariant oder kontravariant markiert werden, indemcovariant=Trueodercontravariant=Trueübergeben wird. Standardmäßig sind manuell erstellte Typparameter invariant. Weitere Informationen finden Sie in PEP 484 und PEP 695.Gebundene Typparameter und eingeschränkte Typparameter haben in mehreren wichtigen Punkten unterschiedliche Semantiken. Die Verwendung eines *gebundenen* Typparameters bedeutet, dass der
TypeVarmit dem höchstmöglichen Typ gelöst wird.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
Die Obergrenze eines Typparameters kann ein konkreter Typ, ein abstrakter Typ (ABC oder Protokoll) oder sogar eine Vereinigung von Typen sein.
# 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
Die Verwendung eines *eingeschränkten* Typparameters bedeutet jedoch, dass der
TypeVarimmer nur als exakt einer der angegebenen Einschränkungen gelöst werden kann.a = concatenate('one', 'two') reveal_type(a) # revealed type is str b = concatenate(StringSubclass('one'), StringSubclass('two')) reveal_type(b) # revealed type is str, despite StringSubclass being passed in c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both
Zur Laufzeit löst
isinstance(x, T)eineTypeErroraus.- __name__¶
Der Name des Typparameters.
- __covariant__¶
Ob der Typparameter explizit als kovariant markiert wurde.
- __contravariant__¶
Ob der Typparameter explizit als kontravariant markiert wurde.
- __infer_variance__¶
Ob die Varianz des Typparameters von Typenprüfern abgeleitet werden soll.
Hinzugefügt in Version 3.12.
- __bound__¶
Die Obergrenze des Typparameters, falls vorhanden.
Geändert in Version 3.12: Für Typparameter, die über die Typparametersyntax erstellt wurden, wird die Obergrenze erst ausgewertet, wenn auf das Attribut zugegriffen wird, nicht wenn der Typparameter erstellt wird (siehe Lazy Evaluation).
- evaluate_bound()¶
Eine Auswertungsfunktion, die dem Attribut
__bound__entspricht. Wenn sie direkt aufgerufen wird, unterstützt diese Methode nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__bound__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format auszuwerten.Hinzugefügt in Version 3.14.
- __constraints__¶
Ein Tupel, das die Einschränkungen des Typparameters, falls vorhanden, enthält.
Geändert in Version 3.12: Für Typparameter, die über die Typparametersyntax erstellt wurden, werden die Einschränkungen erst ausgewertet, wenn auf das Attribut zugegriffen wird, nicht wenn der Typparameter erstellt wird (siehe Lazy Evaluation).
- evaluate_constraints()¶
Eine Auswertungsfunktion, die dem Attribut
__constraints__entspricht. Wenn sie direkt aufgerufen wird, unterstützt diese Methode nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__constraints__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format auszuwerten.Hinzugefügt in Version 3.14.
- __default__¶
Der Standardwert des Typparameters oder
typing.NoDefault, wenn kein Standardwert vorhanden ist.Hinzugefügt in Version 3.13.
- evaluate_default()¶
Eine Auswertungsfunktion, die dem Attribut
__default__entspricht. Wenn sie direkt aufgerufen wird, unterstützt diese Methode nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__default__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format auszuwerten.Hinzugefügt in Version 3.14.
- has_default()¶
Gibt zurück, ob der Typparameter einen Standardwert hat. Dies ist äquivalent zur Prüfung, ob
__default__nicht dietyping.NoDefault-Singleton ist, außer dass die Auswertung des lazy ausgewerteten Standardwerts nicht erzwungen wird.Hinzugefügt in Version 3.13.
Geändert in Version 3.12: Typparameter können nun über die durch PEP 695 eingeführte Typparameter-Syntax deklariert werden. Der Parameter
infer_variancewurde hinzugefügt.Geändert in Version 3.13: Unterstützung für Standardwerte wurde hinzugefügt.
- class typing.TypeVarTuple(name, *, default=typing.NoDefault)¶
Typparametertupel. Eine spezialisierte Form von Typparameter, die *variadische* Generika ermöglicht.
Typparametertupel können in Typparameterlisten mit einem einzelnen Sternchen (
*) vor dem Namen deklariert werden.def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
Oder durch explizites Aufrufen des
TypeVarTuple-Konstruktors:T = TypeVar("T") Ts = TypeVarTuple("Ts") def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: return (*tup[1:], tup[0])
Ein normales Typparameter ermöglicht die Parametrisierung mit einem einzelnen Typ. Ein Typparametertupel hingegen erlaubt die Parametrisierung mit einer *beliebigen* Anzahl von Typen, indem es wie eine *beliebige* Anzahl von in einem Tupel verpackten Typparametern funktioniert. Zum Beispiel:
# T is bound to int, Ts is bound to () # Return value is (1,), which has type tuple[int] move_first_element_to_last(tup=(1,)) # T is bound to int, Ts is bound to (str,) # Return value is ('spam', 1), which has type tuple[str, int] move_first_element_to_last(tup=(1, 'spam')) # T is bound to int, Ts is bound to (str, float) # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] move_first_element_to_last(tup=(1, 'spam', 3.0)) # This fails to type check (and fails at runtime) # because tuple[()] is not compatible with tuple[T, *Ts] # (at least one element is required) move_first_element_to_last(tup=())
Beachten Sie die Verwendung des Entpackungsoperators
*intuple[T, *Ts]. Konzeptionell können Sie sichTsals ein Tupel von Typparametern(T1, T2, ...)vorstellen.tuple[T, *Ts]würde dann zutuple[T, *(T1, T2, ...)]werden, was äquivalent zutuple[T, T1, T2, ...]ist. (Beachten Sie, dass Sie in älteren Python-Versionen dies möglicherweise stattdessen mitUnpackgeschrieben sehen, z. B.Unpack[Ts].)Typparametertupel müssen *immer* entpackt werden. Dies hilft, Typparametertupel von normalen Typparametern zu unterscheiden.
x: Ts # Not valid x: tuple[Ts] # Not valid x: tuple[*Ts] # The correct way to do it
Typparametertupel können in denselben Kontexten wie normale Typparameter verwendet werden. Zum Beispiel in Klassendefinitionen, Argumenten und Rückgabetypen:
class Array[*Shape]: def __getitem__(self, key: tuple[*Shape]) -> float: ... def __abs__(self) -> "Array[*Shape]": ... def get_shape(self) -> tuple[*Shape]: ...
Typparametertupel können problemlos mit normalen Typparametern kombiniert werden:
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
Beachten Sie jedoch, dass höchstens ein Typparametertupel in einer einzelnen Liste von Typargumenten oder Typparametern erscheinen darf.
x: tuple[*Ts, *Ts] # Not valid class Array[*Shape, *Shape]: # Not valid pass
Schließlich kann ein entpacktes Typparametertupel als Typannotation für
*argsverwendet werden:def call_soon[*Ts]( callback: Callable[[*Ts], None], *args: *Ts ) -> None: ... callback(*args)
Im Gegensatz zu nicht entpackten Annotationen von
*args- z. B.*args: int, was besagen würde, dass *alle* Argumenteintsind - ermöglicht*args: *Tsdie Referenzierung der Typen der *einzelnen* Argumente in*args. Hier können wir dadurch sicherstellen, dass die Typen der ancall_soonübergebenen*argsmit den Typen der (positionalen) Argumente voncallbackübereinstimmen.Weitere Details zu Typparametertupeln finden Sie in PEP 646.
- __name__¶
Der Name des Typparametertupels.
- __default__¶
Der Standardwert des Typparametertupels oder
typing.NoDefault, wenn kein Standardwert vorhanden ist.Hinzugefügt in Version 3.13.
- evaluate_default()¶
Eine Auswertungsfunktion, die dem Attribut
__default__entspricht. Wenn sie direkt aufgerufen wird, unterstützt diese Methode nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__default__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format auszuwerten.Hinzugefügt in Version 3.14.
- has_default()¶
Gibt zurück, ob das Typparametertupel einen Standardwert hat. Dies ist äquivalent zur Prüfung, ob
__default__nicht dietyping.NoDefault-Singleton ist, außer dass die Auswertung des lazy ausgewerteten Standardwerts nicht erzwungen wird.Hinzugefügt in Version 3.13.
Hinzugefügt in Version 3.11.
Geändert in Version 3.12: Typparametertupel können nun über die durch PEP 695 eingeführte Typparameter-Syntax deklariert werden.
Geändert in Version 3.13: Unterstützung für Standardwerte wurde hinzugefügt.
- class typing.ParamSpec(name, *, bound=None, covariant=False, contravariant=False, default=typing.NoDefault)¶
Parameter-Spezifikationsvariable. Eine spezialisierte Version von Typparametern.
In Typparameterlisten können Parameter-Spezifikationen mit zwei Sternchen (
**) deklariert werden:type IntFunc[**P] = Callable[P, int]
Zur Kompatibilität mit Python 3.11 und früher können
ParamSpec-Objekte auch wie folgt erstellt werden:P = ParamSpec('P')
Parameter-Spezifikationsvariablen existieren primär zum Nutzen statischer Typenprüfer. Sie werden verwendet, um die Parametertypen eines Callables an ein anderes Callable weiterzuleiten - ein Muster, das häufig in höherwertigen Funktionen und Decorators vorkommt. Sie sind nur gültig, wenn sie in
Concatenateoder als erstes Argument fürCallableverwendet werden, oder als Parameter für benutzerdefinierte Generika. Weitere Informationen zu generischen Typen finden Sie unterGeneric.Um beispielsweise grundlegende Protokollierung zu einer Funktion hinzuzufügen, kann ein Decorator
add_loggingerstellt werden, um Funktionsaufrufe zu protokollieren. Die Parameter-Spezifikationsvariable teilt dem Typenprüfer mit, dass das an den Decorator übergebene Callable und das daraus zurückgegebene neue Callable voneinander abhängige Typparameter haben: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
Ohne
ParamSpecwar der einfachste Weg, dies zuvor zu annotieren, die Verwendung einesTypeVarmit der ObergrenzeCallable[..., Any]. Dies verursacht jedoch zwei Probleme:Der Typenprüfer kann die
inner-Funktion nicht typisieren, da*argsund**kwargsalsAnytypisiert werden müssen.cast()kann im Körper desadd_logging-Decorators erforderlich sein, wenn dieinner-Funktion zurückgegeben wird, oder der statische Typenprüfer muss angewiesen werden,return innerzu ignorieren.
- args¶
- kwargs¶
Da
ParamSpecsowohl positionelle als auch Schlüsselwortparameter erfasst, könnenP.argsundP.kwargsverwendet werden, um einParamSpecin seine Komponenten zu zerlegen.P.argsrepräsentiert das Tupel der positionellen Parameter in einem gegebenen Aufruf und sollte nur zur Annotation von*argsverwendet werden.P.kwargsrepräsentiert die Abbildung von Schlüsselwortparametern auf ihre Werte in einem gegebenen Aufruf und sollte nur zur Annotation von**kwargsverwendet werden. Beide Attribute erfordern, dass der annotierte Parameter im Gültigkeitsbereich liegt. Zur Laufzeit sindP.argsundP.kwargsInstanzen vonParamSpecArgsbzw.ParamSpecKwargs.
- __name__¶
Der Name der Parameterspezifikation.
- __default__¶
Der Standardwert der Parameterspezifikation oder
typing.NoDefault, falls kein Standardwert vorhanden ist.Hinzugefügt in Version 3.13.
- evaluate_default()¶
Eine evaluate-Funktion, die dem Attribut
__default__entspricht. Wenn diese Methode direkt aufgerufen wird, unterstützt sie nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__default__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format zu evaluieren.Hinzugefügt in Version 3.14.
- has_default()¶
Gibt zurück, ob die Parameterspezifikation einen Standardwert hat. Dies entspricht der Prüfung, ob
__default__nicht das Singletontyping.NoDefaultist, außer dass dies nicht zur Auswertung des lazy ausgewerteten Standardwerts zwingt.Hinzugefügt in Version 3.13.
Mit
covariant=Trueodercontravariant=Trueerstellte Parameterspezifikationsvariablen können verwendet werden, um kovariante oder kontravariante generische Typen zu deklarieren. Das Argumentboundwird ebenfalls akzeptiert, ähnlich wie beiTypeVar. Die genaue Semantik dieser Schlüsselwörter ist jedoch noch nicht festgelegt.Hinzugefügt in Version 3.10.
Geändert in Version 3.12: Parameterspezifikationen können jetzt mit der durch PEP 695 eingeführten Typ-Parameter-Syntax deklariert werden.
Geändert in Version 3.13: Unterstützung für Standardwerte wurde hinzugefügt.
Hinweis
Nur im globalen Geltungsbereich definierte Parameterspezifikationsvariablen können gepickelt werden.
Siehe auch
PEP 612 – Parameter Specification Variables (die PEP, die
ParamSpecundConcatenateeingeführt hat)
- typing.ParamSpecArgs¶
- typing.ParamSpecKwargs¶
Argumente und Schlüsselwortargumentattribute einer
ParamSpec. Das AttributP.argseinerParamSpecist eine Instanz vonParamSpecArgs, undP.kwargsist eine Instanz vonParamSpecKwargs. Sie sind für die Laufzeitinspektion gedacht und haben keine spezielle Bedeutung für statische Typenprüfer.Das Aufrufen von
get_origin()für eines dieser Objekte gibt die ursprünglicheParamSpeczurück>>> from typing import ParamSpec, get_origin >>> P = ParamSpec("P") >>> get_origin(P.args) is P True >>> get_origin(P.kwargs) is P True
Hinzugefügt in Version 3.10.
- class typing.TypeAliasType(name, value, *, type_params=())¶
Der Typ von Typaliasen, die über die
type-Anweisung erstellt wurden.Beispiel
>>> type Alias = int >>> type(Alias) <class 'typing.TypeAliasType'>
Hinzugefügt in Version 3.12.
- __name__¶
Der Name des Typalias
>>> type Alias = int >>> Alias.__name__ 'Alias'
- __module__¶
Der Name des Moduls, in dem der Typalias definiert wurde
>>> type Alias = int >>> Alias.__module__ '__main__'
- __type_params__¶
Die Typ-Parameter des Typalias, oder ein leeres Tupel, wenn der Alias nicht generisch ist
>>> type ListOrSet[T] = list[T] | set[T] >>> ListOrSet.__type_params__ (T,) >>> type NotGeneric = int >>> NotGeneric.__type_params__ ()
- __value__¶
Der Wert des Typalias. Dieser wird lazy ausgewertet, sodass Namen, die in der Definition des Alias verwendet werden, erst aufgelöst werden, wenn auf das Attribut
__value__zugegriffen wird.>>> type Mutually = Recursive >>> type Recursive = Mutually >>> Mutually Mutually >>> Recursive Recursive >>> Mutually.__value__ Recursive >>> Recursive.__value__ Mutually
- evaluate_value()¶
Eine evaluate-Funktion, die dem Attribut
__value__entspricht. Wenn diese Methode direkt aufgerufen wird, unterstützt sie nur das FormatVALUE, was dem direkten Zugriff auf das Attribut__value__entspricht. Das Methodenobjekt kann jedoch anannotationlib.call_evaluate_function()übergeben werden, um den Wert in einem anderen Format zu evaluieren.>>> 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')
Hinzugefügt in Version 3.14.
Entpacken
Typ-Aliase unterstützen das Stern-Entpacken mit der Syntax
*Alias. Dies entspricht der direkten Verwendung vonUnpack[Alias].>>> type Alias = tuple[int, str] >>> type Unpacked = tuple[bool, *Alias] >>> Unpacked.__value__ tuple[bool, typing.Unpack[Alias]]
Hinzugefügt in Version 3.14.
Andere spezielle Direktiven¶
Diese Funktionen und Klassen sollten nicht direkt als Annotationen verwendet werden. Ihr beabsichtigter Zweck ist es, Bausteine für die Erstellung und Deklaration von Typen zu sein.
- class typing.NamedTuple¶
Typ-isierte Version von
collections.namedtuple().Verwendung
class Employee(NamedTuple): name: str id: int
Dies ist äquivalent zu
Employee = collections.namedtuple('Employee', ['name', 'id'])
Um einem Feld einen Standardwert zu geben, können Sie es im Klassenkörper zuweisen.
class Employee(NamedTuple): name: str id: int = 3 employee = Employee('Guido') assert employee.id == 3
Felder mit einem Standardwert müssen nach allen Feldern ohne Standardwert stehen.
Die resultierende Klasse hat ein zusätzliches Attribut
__annotations__, das ein Wörterbuch enthält, das die Feldnamen den Feldtypen zuordnet. (Die Feldnamen befinden sich im Attribut_fieldsund die Standardwerte im Attribut_field_defaults, die beide Teil dernamedtuple()-API sind.)NamedTuple-Unterklassen können auch Docstrings und Methoden haben.class Employee(NamedTuple): """Represents an employee.""" name: str id: int = 3 def __repr__(self) -> str: return f'<Employee {self.name}, id={self.id}>'
NamedTuple-Unterklassen können generisch sein.class Group[T](NamedTuple): key: T group: list[T]
Abwärtskompatible Nutzung
# 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)])
Geändert in Version 3.6: Unterstützung für die PEP 526 Variablensyntax für Annotationen hinzugefügt.
Geändert in Version 3.6.1: Unterstützung für Standardwerte, Methoden und Docstrings hinzugefügt.
Geändert in Version 3.8: Die Attribute
_field_typesund__annotations__sind nun reguläre Wörterbücher anstelle von Instanzen vonOrderedDict.Geändert in Version 3.9: Das Attribut
_field_typeswurde zugunsten des standardmäßigeren Attributs__annotations__entfernt, das dieselben Informationen enthält.Geändert in Version 3.11: Unterstützung für generische Named-Tuples hinzugefügt.
Geändert in Version 3.14: Die Verwendung von
super()(und der Closure-Variable__class__) in Methoden vonNamedTuple-Unterklassen wird nicht unterstützt und verursacht einenTypeError.Veraltet seit Version 3.13, wird entfernt in Version 3.15: Die undokumentierte Schlüsselwortargument-Syntax zum Erstellen von NamedTuple-Klassen (
NT = NamedTuple("NT", x=int)) ist veraltet und wird in 3.15 nicht mehr erlaubt. Verwenden Sie stattdessen die klassenbasierte Syntax oder die funktionale Syntax.Veraltet seit Version 3.13, wird entfernt in Version 3.15: Beim Verwenden der funktionalen Syntax zum Erstellen einer NamedTuple-Klasse ist das Nicht-Übergeben eines Werts an den Parameter 'fields' (
NT = NamedTuple("NT")) veraltet. Das Übergeben vonNonean den Parameter 'fields' (NT = NamedTuple("NT", None)) ist ebenfalls veraltet. Beides wird in Python 3.15 nicht mehr erlaubt. Um eine NamedTuple-Klasse mit 0 Feldern zu erstellen, verwenden Sieclass NT(NamedTuple): passoderNT = NamedTuple("NT", []).
- class typing.NewType(name, tp)¶
Hilfsklasse zur Erstellung von unterscheidbaren Typen mit geringem Overhead.
Ein
NewTypewird von einem Typenprüfer als eigenständiger Typ betrachtet. Zur Laufzeit gibt das Aufrufen einesNewTypejedoch sein Argument unverändert zurück.Verwendung
UserId = NewType('UserId', int) # Declare the NewType "UserId" first_user = UserId(1) # "UserId" returns the argument unchanged at runtime
- __module__¶
Der Name des Moduls, in dem der neue Typ definiert ist.
- __name__¶
Der Name des neuen Typs.
- __supertype__¶
Der Typ, auf dem der neue Typ basiert.
Hinzugefügt in Version 3.5.2.
Geändert in Version 3.10:
NewTypeist nun eine Klasse anstelle einer Funktion.
- class typing.Protocol(Generic)¶
Basisklasse für Protokollklassen.
Protokollklassen werden wie folgt definiert
class Proto(Protocol): def meth(self) -> int: ...
Solche Klassen werden hauptsächlich mit statischen Typenprüfern verwendet, die strukturelle Untertypen (statisches Duck-Typing) erkennen, zum Beispiel
class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check
Weitere Details finden Sie in PEP 544. Protokollklassen, die mit
runtime_checkable()(später beschrieben) dekoriert sind, verhalten sich wie einfache Laufzeitprotokolle, die nur die Anwesenheit gegebener Attribute prüfen und ihre Typensignaturen ignorieren. Protokollklassen ohne diesen Dekorator können nicht als zweites Argument fürisinstance()oderissubclass()verwendet werden.Protokollklassen können generisch sein, zum Beispiel
class GenProto[T](Protocol): def meth(self) -> T: ...
In Code, der mit Python 3.11 oder älter kompatibel sein muss, können generische Protokolle wie folgt geschrieben werden
T = TypeVar("T") class GenProto(Protocol[T]): def meth(self) -> T: ...
Hinzugefügt in Version 3.8.
- @typing.runtime_checkable¶
Markiert eine Protokollklasse als Laufzeitprotokoll.
Ein solches Protokoll kann mit
isinstance()undissubclass()verwendet werden. Dies ermöglicht eine einfache strukturelle Überprüfung, ähnlich wie "one trick ponies" incollections.abcwieIterable. Zum Beispiel@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)
Dieser Dekorator löst einen
TypeErroraus, wenn er auf eine Nicht-Protokollklasse angewendet wird.Hinweis
runtime_checkable()prüft nur die Anwesenheit der erforderlichen Methoden oder Attribute, nicht deren Typensignaturen oder Typen. Zum Beispiel istssl.SSLObjecteine Klasse, daher besteht sie eineissubclass()-Prüfung gegen Callable. Die Methodessl.SSLObject.__init__existiert jedoch nur, um einenTypeErrormit einer aussagekräftigeren Meldung auszulösen, wodurch das Aufrufen (Instanziieren) vonssl.SSLObjectunmöglich wird.Hinweis
Eine
isinstance()-Prüfung gegen ein laufzeitfähiges Protokoll kann im Vergleich zu einerisinstance()-Prüfung gegen eine Nicht-Protokollklasse überraschend langsam sein. Ziehen Sie in Betracht, alternative Idiome wiehasattr()-Aufrufe für strukturelle Prüfungen in leistungskritischem Code zu verwenden.Hinzugefügt in Version 3.8.
Geändert in Version 3.12: Die interne Implementierung von
isinstance()-Prüfungen gegen laufzeitfähige Protokolle verwendet nuninspect.getattr_static()zum Nachschlagen von Attributen (zuvor wurdehasattr()verwendet). Infolgedessen werden einige Objekte, die zuvor als Instanzen eines laufzeitfähigen Protokolls galten, ab Python 3.12 möglicherweise nicht mehr als Instanzen dieses Protokolls betrachtet, und umgekehrt. Die meisten Benutzer werden von dieser Änderung wahrscheinlich nicht betroffen sein.Geändert in Version 3.12: Die Mitglieder eines laufzeitfähigen Protokolls gelten nun zur Laufzeit als "eingefroren", sobald die Klasse erstellt wurde. Monkey-Patching von Attributen auf ein laufzeitfähiges Protokoll funktioniert weiterhin, hat aber keine Auswirkungen auf
isinstance()-Prüfungen, die Objekte mit dem Protokoll vergleichen. Weitere Informationen finden Sie unter Was ist neu in Python 3.12.
- class typing.TypedDict(dict)¶
Spezielle Konstruktion zur Hinzufügung von Typ-Hinweisen zu einem Wörterbuch. Zur Laufzeit ist es ein normales
dict.TypedDictdeklariert einen Wörterbuchtyp, der erwartet, dass alle seine Instanzen eine bestimmte Menge von Schlüsseln haben, wobei jedem Schlüssel ein Wert eines konsistenten Typs zugeordnet ist. Diese Erwartung wird nicht zur Laufzeit überprüft, sondern nur von Typenprüfern erzwungen. Verwendungclass 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')
Eine alternative Methode zur Erstellung eines
TypedDictist die Verwendung der Funktionsaufruf-Syntax. Das zweite Argument muss ein literalesdictsein.Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
Diese funktionale Syntax ermöglicht die Definition von Schlüsseln, die keine gültigen Bezeichner sind, zum Beispiel, weil sie Schlüsselwörter sind oder Bindestriche enthalten, oder wenn Schlüsselnamen nicht gemangelt werden sollen, wie reguläre private Namen.
# 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
Standardmäßig müssen alle Schlüssel in einem
TypedDictvorhanden sein. Es ist möglich, einzelne Schlüssel als nicht erforderlich zu markieren, indemNotRequiredverwendet wird.class Point2D(TypedDict): x: int y: int label: NotRequired[str] # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': NotRequired[str]})
Das bedeutet, dass ein
Point2DTypedDictden Schlüssellabelweglassen kann.Es ist auch möglich, alle Schlüssel standardmäßig als nicht erforderlich zu markieren, indem eine Totalität von
Falseangegeben wird.class Point2D(TypedDict, total=False): x: int y: int # Alternative syntax Point2D = TypedDict('Point2D', {'x': int, 'y': int}, total=False)
Das bedeutet, dass ein
Point2DTypedDicteinen beliebigen der Schlüssel weglassen kann. Es wird erwartet, dass ein Typenprüfer nur ein literalesFalseoderTrueals Wert für das Argumenttotalunterstützt.Trueist der Standardwert und macht alle im Klassenkörper definierten Elemente erforderlich.Einzelne Schlüssel eines
total=FalseTypedDictkönnen mitRequiredals erforderlich markiert werden.class Point2D(TypedDict, total=False): x: Required[int] y: Required[int] label: str # Alternative syntax Point2D = TypedDict('Point2D', { 'x': Required[int], 'y': Required[int], 'label': str }, total=False)
Es ist möglich, dass ein
TypedDict-Typ von einem oder mehreren anderenTypedDict-Typen unter Verwendung der klassenbasierten Syntax erbt. Verwendungclass Point3D(Point2D): z: int
Point3Dhat drei Elemente:x,yundz. Dies entspricht dieser Definitionclass Point3D(TypedDict): x: int y: int z: int
Ein
TypedDictkann nicht von einer Nicht-TypedDict-Klasse erben, außer vonGeneric. Zum Beispielclass 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
Ein
TypedDictkann generisch sein.class Group[T](TypedDict): key: T group: list[T]
Um ein generisches
TypedDictzu erstellen, das mit Python 3.11 oder älter kompatibel ist, erben Sie explizit vonGeneric.T = TypeVar("T") class Group(TypedDict, Generic[T]): key: T group: list[T]
Ein
TypedDictkann über Annotationswörterbücher (siehe Best Practices für Annotationen für weitere Informationen zu Best Practices für Annotationen),__total__,__required_keys__und__optional_keys__introspektiert werden.- __total__¶
Point2D.__total__gibt den Wert des Argumentstotalzurück. Beispiel>>> 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
Dieses Attribut spiegelt *nur* den Wert des Arguments
totalfür die aktuelleTypedDict-Klasse wider, nicht ob die Klasse semantisch total ist. Zum Beispiel kann einTypedDictmit__total__aufTruegesetzt haben Schlüssel, die mitNotRequiredmarkiert sind, oder er kann von einem anderenTypedDictmittotal=Falseerben. Daher ist es im Allgemeinen besser,__required_keys__und__optional_keys__für die Introspektion zu verwenden.
- __required_keys__¶
Hinzugefügt in Version 3.9.
- __optional_keys__¶
Point2D.__required_keys__undPoint2D.__optional_keys__gebenfrozenset-Objekte zurück, die die erforderlichen und nicht erforderlichen Schlüssel enthalten, bzw. die nicht erforderlichen Schlüssel.Mit
Requiredmarkierte Schlüssel erscheinen immer in__required_keys__, und mitNotRequiredmarkierte Schlüssel erscheinen immer in__optional_keys__.Für Abwärtskompatibilität mit Python 3.10 und älter ist es auch möglich, Vererbung zu verwenden, um sowohl erforderliche als auch nicht erforderliche Schlüssel im selben
TypedDictzu deklarieren. Dies geschieht, indem einTypedDictmit einem Wert für dastotal-Argument deklariert und dann von einem anderenTypedDictmit einem anderen Wert fürtotalabgeleitet wird.>>> 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
Hinzugefügt in Version 3.9.
Hinweis
Wenn
from __future__ import annotationsverwendet wird oder wenn Annotationen als Zeichenketten gegeben sind, werden Annotationen nicht ausgewertet, wenn dasTypedDictdefiniert wird. Daher funktionieren die Laufzeit-Introspektionen, auf denen__required_keys__und__optional_keys__basieren, möglicherweise nicht richtig, und die Werte der Attribute können falsch sein.
Die Unterstützung für
ReadOnlyspiegelt sich in den folgenden Attributen wider- __readonly_keys__¶
Ein
frozenset, der die Namen aller schreibgeschützten Schlüssel enthält. Schlüssel sind schreibgeschützt, wenn sie denReadOnly-Qualifizierer tragen.Hinzugefügt in Version 3.13.
- __mutable_keys__¶
Ein
frozenset, der die Namen aller veränderlichen Schlüssel enthält. Schlüssel sind veränderlich, wenn sie denReadOnly-Qualifizierer nicht tragen.Hinzugefügt in Version 3.13.
Weitere Beispiele und detaillierte Regeln finden Sie im Abschnitt TypedDict in der Typdokumentation.
Hinzugefügt in Version 3.8.
Geändert in Version 3.11: Unterstützung für die Kennzeichnung einzelner Schlüssel als
RequiredoderNotRequiredhinzugefügt. Siehe PEP 655.Geändert in Version 3.11: Unterstützung für generische
TypedDicts hinzugefügt.Geändert in Version 3.13: Unterstützung für die Keyword-Argument-Methode zur Erstellung von
TypedDicts entfernt.Geändert in Version 3.13: Unterstützung für den
ReadOnly-Qualifizierer hinzugefügt.Vom Vorgänger seit Version 3.13, wird in Version 3.15 entfernt: Bei Verwendung der funktionalen Syntax zum Erstellen einer TypedDict-Klasse ist es veraltet, dem Parameter 'fields' keinen Wert zu übergeben (
TD = TypedDict("TD")). Die Übergabe vonNonean den 'fields'-Parameter (TD = TypedDict("TD", None)) ist ebenfalls veraltet. Beide werden in Python 3.15 nicht mehr zugelassen. Um eine TypedDict-Klasse mit 0 Feldern zu erstellen, verwenden Sieclass TD(TypedDict): passoderTD = TypedDict("TD", {}).
Protokolle¶
Die folgenden Protokolle werden vom Modul typing bereitgestellt. Alle sind mit @runtime_checkable dekoriert.
- class typing.SupportsAbs¶
Eine ABC mit einer abstrakten Methode
__abs__, die in ihrem Rückgabetyp kovariant ist.
- class typing.SupportsBytes¶
Eine ABC mit einer abstrakten Methode
__bytes__.
- class typing.SupportsComplex¶
Eine ABC mit einer abstrakten Methode
__complex__.
- class typing.SupportsFloat¶
Eine ABC mit einer abstrakten Methode
__float__.
- class typing.SupportsIndex¶
Eine ABC mit einer abstrakten Methode
__index__.Hinzugefügt in Version 3.8.
- class typing.SupportsInt¶
Eine ABC mit einer abstrakten Methode
__int__.
- class typing.SupportsRound¶
Eine ABC mit einer abstrakten Methode
__round__, die in ihrem Rückgabetyp kovariant ist.
ABCs und Protokolle für die Arbeit mit I/O¶
- class typing.IO[AnyStr]¶
- class typing.TextIO[AnyStr]¶
- class typing.BinaryIO[AnyStr]¶
Die generische Klasse
IO[AnyStr]und ihre UnterklassenTextIO(IO[str])undBinaryIO(IO[bytes])repräsentieren die Typen von I/O-Streams wie die vonopen()zurückgegebenen. Bitte beachten Sie, dass diese Klassen keine Protokolle sind und ihre Schnittstelle recht breit gefasst ist.
Die Protokolle io.Reader und io.Writer bieten eine einfachere Alternative für Argumenttypen, wenn nur die Methoden read() oder write() zugegriffen werden, jeweils
def read_and_write(reader: Reader[str], writer: Writer[bytes]):
data = reader.read()
writer.write(data.encode())
Ziehen Sie auch die Verwendung von collections.abc.Iterable für die Iteration über die Zeilen eines Eingabestreams in Betracht
def read_config(stream: Iterable[str]):
for line in stream:
...
Funktionen und Dekoratoren¶
- typing.cast(typ, val)¶
Wirft einen Wert auf einen Typ.
Dies gibt den Wert unverändert zurück. Für den Typprüfer signalisiert dies, dass der Rückgabewert den angegebenen Typ hat, aber zur Laufzeit wird absichtlich nichts überprüft (wir wollen, dass dies so schnell wie möglich ist).
- typing.assert_type(val, typ, /)¶
Fordert einen statischen Typprüfer auf, zu bestätigen, dass val den abgeleiteten Typ typ hat.
Zur Laufzeit tut dies nichts: Es gibt das erste Argument unverändert und ohne Prüfungen oder Nebeneffekte zurück, unabhängig vom tatsächlichen Typ des Arguments.
Wenn ein statischer Typprüfer auf einen Aufruf von
assert_type()stößt, gibt er einen Fehler aus, wenn der Wert nicht vom angegebenen Typ ist.def greet(name: str) -> None: assert_type(name, str) # OK, inferred type of `name` is `str` assert_type(name, int) # type checker error
Diese Funktion ist nützlich, um sicherzustellen, dass das Verständnis eines Skripts durch den Typprüfer mit den Absichten des Entwicklers übereinstimmt.
def complex_function(arg: object): # Do some complex type-narrowing logic, # after which we hope the inferred type will be `int` ... # Test whether the type checker correctly understands our function assert_type(arg, int)
Hinzugefügt in Version 3.11.
- typing.assert_never(arg, /)¶
Fordert einen statischen Typprüfer auf, zu bestätigen, dass eine Codezeile nicht erreichbar ist.
Beispiel
def int_or_str(arg: int | str) -> None: match arg: case int(): print("It's an int") case str(): print("It's a str") case _ as unreachable: assert_never(unreachable)
Hier erlauben die Annotationen dem Typprüfer, abzuleiten, dass der letzte Fall niemals ausgeführt werden kann, da
argentweder einintoder einstrist und beide Optionen durch frühere Fälle abgedeckt sind.Wenn ein Typprüfer feststellt, dass ein Aufruf von
assert_never()erreichbar ist, gibt er einen Fehler aus. Wenn beispielsweise die Typannotation fürargstattdessenint | str | floatwäre, würde der Typprüfer einen Fehler ausgeben, der darauf hinweist, dassunreachablevom Typfloatist. Damit ein Aufruf vonassert_neverdie Typprüfung besteht, muss der abgeleitete Typ des übergebenen Arguments der unterste Typ,Never, sein und nichts anderes.Zur Laufzeit löst dies eine Ausnahme aus, wenn es aufgerufen wird.
Siehe auch
Unerreichbarer Code und Vollständigkeitsprüfung enthält weitere Informationen zur Vollständigkeitsprüfung mit statischer Typisierung.
Hinzugefügt in Version 3.11.
- typing.reveal_type(obj, /)¶
Fordert einen statischen Typprüfer auf, den abgeleiteten Typ eines Ausdrucks preiszugeben.
Wenn ein statischer Typprüfer auf einen Aufruf dieser Funktion stößt, gibt er eine Diagnose mit dem abgeleiteten Typ des Arguments aus. Zum Beispiel
x: int = 1 reveal_type(x) # Revealed type is "builtins.int"
Dies kann nützlich sein, wenn Sie debuggen möchten, wie Ihr Typprüfer mit einem bestimmten Codeausschnitt umgeht.
Zur Laufzeit gibt diese Funktion den Laufzeittyp ihres Arguments an
sys.stderraus und gibt das Argument unverändert zurück (wodurch der Aufruf innerhalb eines Ausdrucks verwendet werden kann).x = reveal_type(1) # prints "Runtime type is int" print(x) # prints "1"
Beachten Sie, dass der Laufzeittyp vom Typ, der statisch von einem Typprüfer abgeleitet wurde, abweichen kann (weniger oder spezifischer).
Die meisten Typprüfer unterstützen
reveal_type()überall, auch wenn der Name nicht vontypingimportiert wurde. Das Importieren des Namens vontypingermöglicht jedoch, dass Ihr Code ohne Laufzeitfehler ausgeführt wird und die Absicht klarer kommuniziert.Hinzugefügt in Version 3.11.
- @typing.dataclass_transform(*, eq_default=True, order_default=False, kw_only_default=False, frozen_default=False, field_specifiers=(), **kwargs)¶
Dekorator zur Kennzeichnung eines Objekts, das
dataclass-ähnliches Verhalten aufweist.dataclass_transformkann verwendet werden, um eine Klasse, eine Metaklasse oder eine Funktion zu dekorieren, die selbst ein Dekorator ist. Die Anwesenheit von@dataclass_transform()teilt einem statischen Typprüfer mit, dass das dekorierte Objekt zur Laufzeit "Magie" ausführt, die eine Klasse ähnlich wie@dataclasses.dataclasstransformiert.Beispiel für die Verwendung mit einer Dekoratorfunktion
@dataclass_transform() def create_model[T](cls: type[T]) -> type[T]: ... return cls @create_model class CustomerModel: id: int name: str
Auf einer Basisklasse
@dataclass_transform() class ModelBase: ... class CustomerModel(ModelBase): id: int name: str
Auf einer Metaklasse
@dataclass_transform() class ModelMeta(type): ... class ModelBase(metaclass=ModelMeta): ... class CustomerModel(ModelBase): id: int name: str
Die oben definierten
CustomerModel-Klassen werden von Typprüfern ähnlich wie mit@dataclasses.dataclasserstellte Klassen behandelt. Zum Beispiel gehen Typprüfer davon aus, dass diese Klassen__init__-Methoden haben, dieidundnameakzeptieren.Die dekorierten Klasse, Metaklasse oder Funktion können die folgenden booleschen Argumente akzeptieren, von denen Typprüfer annehmen, dass sie die gleiche Wirkung haben wie beim
@dataclasses.dataclass-Dekorator:init,eq,order,unsafe_hash,frozen,match_args,kw_onlyundslots. Es muss möglich sein, den Wert dieser Argumente (TrueoderFalse) statisch auszuwerten.Die Argumente des
dataclass_transform-Dekorators können verwendet werden, um die Standardverhalten der dekorierten Klasse, Metaklasse oder Funktion anzupassen.- Parameter:
eq_default (bool) – Zeigt an, ob angenommen wird, dass der Parameter
eqTrueoderFalseist, wenn er vom Aufrufer weggelassen wird. StandardmäßigTrue.order_default (bool) – Zeigt an, ob angenommen wird, dass der Parameter
orderTrueoderFalseist, wenn er vom Aufrufer weggelassen wird. StandardmäßigFalse.kw_only_default (bool) – Zeigt an, ob angenommen wird, dass der Parameter
kw_onlyTrueoderFalseist, wenn er vom Aufrufer weggelassen wird. StandardmäßigFalse.frozen_default (bool) –
Zeigt an, ob angenommen wird, dass der Parameter
frozenTrueoderFalseist, wenn er vom Aufrufer weggelassen wird. StandardmäßigFalse.Hinzugefügt in Version 3.12.
field_specifiers (tuple[Callable[..., Any], ...]) – Gibt eine statische Liste unterstützter Klassen oder Funktionen an, die Felder beschreiben, ähnlich wie
dataclasses.field(). Standardmäßig().**kwargs (Any) – Beliebige andere Schlüsselwortargumente werden akzeptiert, um mögliche zukünftige Erweiterungen zu ermöglichen.
Typprüfer erkennen die folgenden optionalen Parameter bei Feldangaben
Erkannte Parameter für Feldangaben¶ Parametername
Beschreibung
initZeigt an, ob das Feld in die synthetisierte
__init__-Methode aufgenommen werden soll. Wenn nicht angegeben, istinitstandardmäßigTrue.defaultGibt den Standardwert für das Feld an.
default_factoryGibt eine Laufzeit-Callback-Funktion an, die den Standardwert für das Feld zurückgibt. Wenn weder
defaultnochdefault_factoryangegeben sind, wird angenommen, dass das Feld keinen Standardwert hat und bei der Instanziierung der Klasse ein Wert bereitgestellt werden muss.factoryEin Alias für den Parameter
default_factorybei Feldangaben.kw_onlyZeigt an, ob das Feld als nur mit Schlüsselwort zu übergebend gekennzeichnet werden soll. Wenn
True, ist das Feld nur mit Schlüsselwort zu übergebend. WennFalse, ist es nicht nur mit Schlüsselwort zu übergebend. Wenn nicht angegeben, wird der Wert des Parameterskw_onlydes mitdataclass_transformdekorierten Objekts verwendet, oder wenn dieser nicht angegeben ist, der Wert vonkw_only_defaultaufdataclass_transformverwendet.aliasGibt einen alternativen Namen für das Feld an. Dieser alternative Name wird in der synthetisierten
__init__-Methode verwendet.Zur Laufzeit zeichnet dieser Dekorator seine Argumente im Attribut
__dataclass_transform__des dekorierten Objekts auf. Er hat keine anderen Laufzeitwirkungen.Weitere Details finden Sie in PEP 681.
Hinzugefügt in Version 3.11.
- @typing.overload¶
Dekorator zum Erstellen überladener Funktionen und Methoden.
Der Dekorator
@overloadermöglicht die Beschreibung von Funktionen und Methoden, die mehrere verschiedene Kombinationen von Argumenttypen unterstützen. Eine Reihe von mit@overloaddekorierten Definitionen muss von genau einer nicht mit@overloaddekorierten Definition (für dieselbe Funktion/Methode) gefolgt werden.Mit
@overloaddekorierte Definitionen sind nur für den Typprüfer bestimmt, da sie von der nicht mit@overloaddekorierten Definition überschrieben werden. Die nicht mit@overloaddekorierte Definition wird hingegen zur Laufzeit verwendet, sollte aber von einem Typprüfer ignoriert werden. Zur Laufzeit löst der direkte Aufruf einer mit@overloaddekorierten Funktion eineNotImplementedErroraus.Ein Beispiel für eine Überladung, die einen präziseren Typ liefert, als mit einer Union oder einem Typvariablen ausgedrückt werden kann
@overload def process(response: None) -> None: ... @overload def process(response: int) -> tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): ... # actual implementation goes here
Weitere Details und ein Vergleich mit anderen Typisierungssemantiken finden Sie in PEP 484.
Geändert in Version 3.11: Überladene Funktionen können jetzt zur Laufzeit mit
get_overloads()introspektiert werden.
- typing.get_overloads(func)¶
Gibt eine Sequenz von mit
@overloaddekorierten Definitionen für func zurück.func ist das Funktions-Objekt für die Implementierung der überladenen Funktion. Gegeben die Definition von
processin der Dokumentation von@overload, gibtget_overloads(process)eine Sequenz von drei Funktions-Objekten für die drei definierten Überladungen zurück. Wenn aufgerufen auf eine Funktion ohne Überladungen, gibtget_overloads()eine leere Sequenz zurück.get_overloads()kann zur Introspektion einer überladenen Funktion zur Laufzeit verwendet werden.Hinzugefügt in Version 3.11.
- typing.clear_overloads()¶
Löscht alle registrierten Überladungen im internen Register.
Dies kann verwendet werden, um den vom Register verwendeten Speicher zurückzufordern.
Hinzugefügt in Version 3.11.
- @typing.final¶
Dekorator zur Kennzeichnung von finalen Methoden und finalen Klassen.
Das Dekorieren einer Methode mit
@finalzeigt einem Typprüfer an, dass die Methode in einer Unterklasse nicht überschrieben werden kann. Das Dekorieren einer Klasse mit@finalzeigt an, dass sie nicht unterklassifiziert werden kann.Zum Beispiel
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 ...
Es gibt keine Laufzeitüberprüfung dieser Eigenschaften. Weitere Einzelheiten finden Sie in PEP 591.
Hinzugefügt in Version 3.8.
Geändert in Version 3.11: Der Dekorator versucht nun, ein Attribut
__final__aufTruedes dekorierten Objekts zu setzen. Daher kann eine Überprüfung wieif getattr(obj, "__final__", False)zur Laufzeit verwendet werden, um festzustellen, ob ein Objektobjals final markiert wurde. Wenn das dekorierte Objekt das Setzen von Attributen nicht unterstützt, gibt der Dekorator das Objekt unverändert zurück, ohne eine Ausnahme auszulösen.
- @typing.no_type_check¶
Dekorator, um anzuzeigen, dass Annotationen keine Typenhinweise sind.
Dies funktioniert als Klassen- oder FunktionsDekorator. Bei einer Klasse wird dies rekursiv auf alle in dieser Klasse definierten Methoden und Klassen angewendet (aber nicht auf Methoden, die in ihren Oberklassen oder Unterklassen definiert sind). Typ-Checker ignorieren alle Annotationen in einer Funktion oder Klasse mit diesem Dekorator.
@no_type_checkverändert das dekorierte Objekt direkt.
- @typing.no_type_check_decorator¶
Dekorator, um einem anderen Dekorator den
no_type_check()-Effekt zu verleihen.Dies umschließt den Dekorator mit etwas, das die dekorierte Funktion mit
no_type_check()umschließt.Veraltet seit Version 3.13, wird entfernt in Version 3.15: Kein Typ-Checker hat jemals Unterstützung für
@no_type_check_decoratorhinzugefügt. Er ist daher veraltet und wird in Python 3.15 entfernt.
- @typing.override¶
Dekorator, um anzuzeigen, dass eine Methode in einer Unterklasse dazu bestimmt ist, eine Methode oder ein Attribut einer Oberklasse zu überschreiben.
Typ-Checker sollten einen Fehler ausgeben, wenn eine mit
@overridedekorierte Methode tatsächlich nichts überschreibt. Dies hilft, Fehler zu vermeiden, die auftreten können, wenn eine Basisklasse geändert wird, ohne dass eine entsprechende Änderung in einer Kindklasse vorgenommen wird.Zum Beispiel
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 ...
Es gibt keine Laufzeitüberprüfung dieser Eigenschaft.
Der Dekorator versucht, ein Attribut
__override__aufTruedes dekorierten Objekts zu setzen. Daher kann eine Überprüfung wieif getattr(obj, "__override__", False)zur Laufzeit verwendet werden, um festzustellen, ob ein Objektobjals überschrieben markiert wurde. Wenn das dekorierte Objekt das Setzen von Attributen nicht unterstützt, gibt der Dekorator das Objekt unverändert zurück, ohne eine Ausnahme auszulösen.Weitere Einzelheiten finden Sie in PEP 698.
Hinzugefügt in Version 3.12.
- @typing.type_check_only¶
Dekorator, um eine Klasse oder Funktion als zur Laufzeit nicht verfügbar zu markieren.
Dieser Dekorator ist selbst zur Laufzeit nicht verfügbar. Er dient hauptsächlich dazu, Klassen zu markieren, die in Typ-Stub-Dateien definiert sind, wenn eine Implementierung eine Instanz einer privaten Klasse zurückgibt.
@type_check_only class Response: # private or not available at runtime code: int def get_header(self, name: str) -> str: ... def fetch_response() -> Response: ...
Beachten Sie, dass die Rückgabe von Instanzen privater Klassen nicht empfohlen wird. Es ist normalerweise vorzuziehen, solche Klassen öffentlich zu machen.
Introspektionshilfen¶
- typing.get_type_hints(obj, globalns=None, localns=None, include_extras=False)¶
Gibt ein Wörterbuch mit Typenhinweisen für ein Funktions-, Methoden-, Modul- oder Klassenobjekt zurück.
Dies ist oft dasselbe wie
obj.__annotations__, aber diese Funktion nimmt die folgenden Änderungen am Annotationswörterbuch vor:Vorwärtsverweise, die als Zeichenkettenliterale oder
ForwardRef-Objekte kodiert sind, werden durch Auswertung in globalns, localns und (wo zutreffend) dem Typenparameter-Namensraum von obj behandelt. Wenn globalns oder localns nicht angegeben sind, werden entsprechende Namensraum-Wörterbücher aus obj abgeleitet.Nonewird durchtypes.NoneTypeersetzt.Wenn
@no_type_checkauf obj angewendet wurde, wird ein leeres Wörterbuch zurückgegeben.Wenn obj eine Klasse
Cist, gibt die Funktion ein Wörterbuch zurück, das Annotationen von Basisklassen vonCmit denen vonCdirekt zusammenführt. Dies geschieht durch Traversierung vonC.__mro__und iteratives Kombinieren von__annotations__-Wörterbüchern. Annotationen in Klassen, die früher in der Methodenauflösungsreihenfolge erscheinen, haben immer Vorrang vor Annotationen in Klassen, die später in der Methodenauflösungsreihenfolge erscheinen.Die Funktion ersetzt rekursiv alle Vorkommen von
Annotated[T, ...]durchT, es sei denn, include_extras ist aufTruegesetzt (sieheAnnotatedfür weitere Informationen).
Siehe auch
annotationlib.get_annotations(), eine untergeordnete Funktion, die Annotationen direkter zurückgibt.Vorsicht
Diese Funktion kann beliebigen Code ausführen, der in Annotationen enthalten ist. Siehe Sicherheitsaspekte der Introspektion von Annotationen für weitere Informationen.
Hinweis
Wenn Vorwärtsverweise in den Annotationen von obj nicht auflösbar sind oder kein gültiger Python-Code sind, löst diese Funktion eine Ausnahme wie
NameErroraus. Dies kann beispielsweise bei importierten Typen-Aliase der Fall sein, die Vorwärtsverweise enthalten, oder bei Namen, die unterif TYPE_CHECKINGimportiert wurden.Geändert in Version 3.9: Der Parameter
include_extraswurde als Teil von PEP 593 hinzugefügt. Weitere Informationen finden Sie in der Dokumentation zuAnnotated.Geändert in Version 3.11: Zuvor wurde
Optional[t]für Funktions- und Methodenannotationen hinzugefügt, wenn ein Standardwert gleichNonegesetzt war. Jetzt wird die Annotation unverändert zurückgegeben.
- typing.get_origin(tp)¶
Holen Sie sich die nicht subscriptete Version eines Typs: für ein Tippobjekt der Form
X[Y, Z, ...]geben SieXzurück.Wenn
Xein Alias destyping-Moduls für eine eingebaute Klasse oder eine Klasse aus demcollections-Modul ist, wird sie zur ursprünglichen Klasse normalisiert. WennXeine Instanz vonParamSpecArgsoderParamSpecKwargsist, geben Sie das zugrunde liegendeParamSpeczurück. Geben SieNonefür nicht unterstützte Objekte zurück.Beispiele
assert get_origin(str) is None assert get_origin(Dict[str, int]) is dict assert get_origin(Union[int, str]) is Union assert get_origin(Annotated[str, "metadata"]) is Annotated P = ParamSpec('P') assert get_origin(P.args) is P assert get_origin(P.kwargs) is P
Hinzugefügt in Version 3.8.
- typing.get_args(tp)¶
Holen Sie sich Typargumente mit allen durchgeführten Substitutionen: für ein Tippobjekt der Form
X[Y, Z, ...]geben Sie(Y, Z, ...)zurück.Wenn
Xeine Union oderLiteralist, die in einem anderen generischen Typ enthalten ist, kann die Reihenfolge von(Y, Z, ...)aufgrund des Typ-Cachings von der Reihenfolge der ursprünglichen Argumente[Y, Z, ...]abweichen. Geben Sie()für nicht unterstützte Objekte zurück.Beispiele
assert get_args(int) == () assert get_args(Dict[int, str]) == (int, str) assert get_args(Union[int, str]) == (int, str)
Hinzugefügt in Version 3.8.
- typing.get_protocol_members(tp)¶
Gibt die Menge der in einem
Protocoldefinierten Mitglieder zurück.>>> from typing import Protocol, get_protocol_members >>> class P(Protocol): ... def a(self) -> str: ... ... b: int >>> get_protocol_members(P) == frozenset({'a', 'b'}) True
Löst
TypeErrorfür Argumente aus, die keine Protokolle sind.Hinzugefügt in Version 3.13.
- typing.is_protocol(tp)¶
Bestimmen Sie, ob ein Typ ein
Protocolist.Zum Beispiel
class P(Protocol): def a(self) -> str: ... b: int is_protocol(P) # => True is_protocol(int) # => False
Hinzugefügt in Version 3.13.
- typing.is_typeddict(tp)¶
Prüfen Sie, ob ein Typ ein
TypedDictist.Zum Beispiel
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)
Hinzugefügt in Version 3.10.
- class typing.ForwardRef¶
Klasse, die für die interne Typenrepräsentation von Zeichenketten-Vorwärtsverweisen verwendet wird.
Zum Beispiel wird
List["SomeClass"]implizit inList[ForwardRef("SomeClass")]umgewandelt.ForwardRefsollte nicht von einem Benutzer instanziiert werden, kann aber von Introspektionswerkzeugen verwendet werden.Hinweis
PEP 585 generische Typen wie
list["SomeClass"]werden nicht implizit inlist[ForwardRef("SomeClass")]umgewandelt und werden daher nicht automatisch zulist[SomeClass]aufgelöst.Hinzugefügt in Version 3.7.4.
Geändert in Version 3.14: Dies ist jetzt ein Alias für
annotationlib.ForwardRef. Mehrere undokumentierte Verhaltensweisen dieser Klasse wurden geändert; zum Beispiel wird nach der Auswertung einesForwardRefder ausgewertete Wert nicht mehr zwischengespeichert.
- typing.evaluate_forward_ref(forward_ref, *, owner=None, globals=None, locals=None, type_params=None, format=annotationlib.Format.VALUE)¶
Werten Sie eine
annotationlib.ForwardRefals Typenhinweis aus.Dies ähnelt dem Aufruf von
annotationlib.ForwardRef.evaluate(), aber im Gegensatz zu dieser Methode wertetevaluate_forward_ref()auch Vorwärtsverweise aus, die innerhalb des Typenhinweises verschachtelt sind, rekursiv aus.Siehe die Dokumentation für
annotationlib.ForwardRef.evaluate()für die Bedeutung der Parameter owner, globals, locals, type_params und format.Vorsicht
Diese Funktion kann beliebigen Code ausführen, der in Annotationen enthalten ist. Siehe Sicherheitsaspekte der Introspektion von Annotationen für weitere Informationen.
Hinzugefügt in Version 3.14.
- typing.NoDefault¶
Ein Sentinel-Objekt, das verwendet wird, um anzuzeigen, dass ein Typenparameter keinen Standardwert hat. Zum Beispiel
>>> T = TypeVar("T") >>> T.__default__ is typing.NoDefault True >>> S = TypeVar("S", default=None) >>> S.__default__ is None True
Hinzugefügt in Version 3.13.
Konstante¶
- typing.TYPE_CHECKING¶
Eine spezielle Konstante, die von externen statischen Typ-Checkern als
Trueangenommen wird. Zur Laufzeit ist sieFalse.Ein Modul, dessen Import aufwendig ist und das nur Typen enthält, die für Typenannotationen verwendet werden, kann sicher innerhalb eines
if TYPE_CHECKING:-Blocks importiert werden. Dies verhindert, dass das Modul zur Laufzeit tatsächlich importiert wird; Annotationen werden nicht eifrig ausgewertet (siehe PEP 649), daher ist die Verwendung nicht definierter Symbole in Annotationen harmlos – solange Sie sie nicht später untersuchen. Ihr statisches Typanalyse-Tool setztTYPE_CHECKINGwährend der statischen Typanalyse aufTrue, was bedeutet, dass das Modul importiert wird und die Typen während der Analyse ordnungsgemäß geprüft werden.Verwendung
if TYPE_CHECKING: import expensive_mod def fun(arg: expensive_mod.SomeType) -> None: local_var: expensive_mod.AnotherType = other_fun()
Wenn Sie gelegentlich Typenannotationen zur Laufzeit untersuchen müssen, die nicht definierte Symbole enthalten könnten, verwenden Sie
annotationlib.get_annotations()mit einemformat-Parameter vonannotationlib.Format.STRINGoderannotationlib.Format.FORWARDREF, um die Annotationen sicher abzurufen, ohneNameErrorauszulösen.Hinzugefügt in Version 3.5.2.
Veraltete Aliase¶
Dieses Modul definiert mehrere veraltete Aliase für bereits vorhandene Standardbibliotheksklassen. Diese wurden ursprünglich in das typing-Modul aufgenommen, um die Parametrisierung dieser generischen Klassen mit [] zu unterstützen. Die Aliase wurden jedoch in Python 3.9 überflüssig, als die entsprechenden vorhandenen Klassen für die Unterstützung von [] erweitert wurden (siehe PEP 585).
Die redundanten Typen sind ab Python 3.9 veraltet. Obwohl die Aliase irgendwann entfernt werden könnten, ist die Entfernung dieser Aliase derzeit nicht geplant. Daher werden von der Interpreter für diese Aliase keine Deprecation-Warnungen ausgegeben.
Wenn zu einem späteren Zeitpunkt beschlossen wird, diese veralteten Aliase zu entfernen, wird die Interpreter mindestens zwei Releases vor der Entfernung eine Deprecation-Warnung ausgeben. Die Aliase werden garantiert bis mindestens Python 3.14 ohne Deprecation-Warnungen im typing-Modul vorhanden sein.
Typ-Checker werden ermutigt, die Verwendung der veralteten Typen zu kennzeichnen, wenn das von ihnen geprüfte Programm eine minimale Python-Version von 3.9 oder neuer anstrebt.
Aliase für eingebaute Typen¶
- class typing.Dict(dict, MutableMapping[KT, VT])¶
Veralteter Alias für
dict.Beachten Sie, dass es zur Annotation von Argumenten bevorzugt wird, einen abstrakten Sammlungstyp wie
Mappingzu verwenden, anstattdictodertyping.Dictzu verwenden.Veraltet seit Version 3.9:
builtins.dictunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.List(list, MutableSequence[T])¶
Veralteter Alias für
list.Beachten Sie, dass es zur Annotation von Argumenten bevorzugt wird, einen abstrakten Sammlungstyp wie
SequenceoderIterablezu verwenden, anstattlistodertyping.Listzu verwenden.Veraltet seit Version 3.9:
builtins.listunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.Set(set, MutableSet[T])¶
Veralteter Alias für
builtins.set.Beachten Sie, dass es zur Annotation von Argumenten bevorzugt wird, einen abstrakten Sammlungstyp wie
collections.abc.Setzu verwenden, anstattsetodertyping.Setzu verwenden.Veraltet seit Version 3.9:
builtins.setunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.FrozenSet(frozenset, AbstractSet[T_co])¶
Veralteter Alias für
builtins.frozenset.Veraltet seit Version 3.9:
builtins.frozensetunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- typing.Tuple¶
Veralteter Alias für
tuple.tupleundTuplesind im Typensystem speziell behandelt; siehe Annotation von Tupeln für weitere Details.Veraltet seit Version 3.9:
builtins.tupleunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.Type(Generic[CT_co])¶
Veralteter Alias für
type.Siehe Der Typ von Klassenobjekten für Details zur Verwendung von
typeodertyping.Typein Typannotationen.Hinzugefügt in Version 3.5.2.
Veraltet seit Version 3.9:
builtins.typeunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
Aliase für Typen in collections¶
- class typing.DefaultDict(collections.defaultdict, MutableMapping[KT, VT])¶
Veralteter Alias für
collections.defaultdict.Hinzugefügt in Version 3.5.2.
Veraltet seit Version 3.9:
collections.defaultdictunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.OrderedDict(collections.OrderedDict, MutableMapping[KT, VT])¶
Veralteter Alias für
collections.OrderedDict.Hinzugefügt in Version 3.7.2.
Veraltet seit Version 3.9:
collections.OrderedDictunterstützt jetzt das Subscripting ([]). Siehe PEP 585 und Generischer Alias-Typ.
- class typing.ChainMap(collections.ChainMap, MutableMapping[KT, VT])¶
Veralteter Alias für
collections.ChainMap.Hinzugefügt in Version 3.6.1.
Seit Version 3.9 veraltet:
collections.ChainMapunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Counter(collections.Counter, Dict[T, int])¶
Veralteter Alias für
collections.Counter.Hinzugefügt in Version 3.6.1.
Seit Version 3.9 veraltet:
collections.Counterunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Deque(deque, MutableSequence[T])¶
Veralteter Alias für
collections.deque.Hinzugefügt in Version 3.6.1.
Seit Version 3.9 veraltet:
collections.dequeunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
Aliase zu anderen konkreten Typen¶
- class typing.Pattern¶
- class typing.Match¶
Veraltete Aliase, die den Rückgabetypen von
re.compile()undre.match()entsprechen.Diese Typen (und die entsprechenden Funktionen) sind generisch über
AnyStr.Patternkann alsPattern[str]oderPattern[bytes]spezialisiert werden;Matchkann alsMatch[str]oderMatch[bytes]spezialisiert werden.Seit Version 3.9 veraltet: Die Klassen
PatternundMatchausreunterstützen jetzt[]. Siehe PEP 585 und Generic Alias Type.
- class typing.Text¶
Veralteter Alias für
str.Textwird bereitgestellt, um einen zukunftskompatiblen Pfad für Python 2-Code zu schaffen: in Python 2 istTextein Alias fürunicode.Verwenden Sie
Text, um anzugeben, dass ein Wert einen Unicode-String auf eine Weise enthalten muss, die sowohl mit Python 2 als auch mit Python 3 kompatibel ist.def add_unicode_checkmark(text: Text) -> Text: return text + u' \u2713'
Hinzugefügt in Version 3.5.2.
Seit Version 3.11 veraltet: Python 2 wird nicht mehr unterstützt, und die meisten Type-Checker unterstützen auch keine Typüberprüfung für Python 2-Code mehr. Die Entfernung des Alias ist derzeit nicht geplant, aber Benutzer werden ermutigt,
stranstelle vonTextzu verwenden.
Aliase zu Container-ABCs in collections.abc¶
- class typing.AbstractSet(Collection[T_co])¶
Veralteter Alias für
collections.abc.Set.Seit Version 3.9 veraltet:
collections.abc.Setunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.ByteString(Sequence[int])¶
Veralteter Alias für
collections.abc.ByteString.Verwenden Sie
isinstance(obj, collections.abc.Buffer), um zur Laufzeit zu testen, obobjdas Pufferprotokoll implementiert. Für die Verwendung in Typannotationen verwenden Sie entwederBufferoder eine Union, die explizit die Typen angibt, die Ihr Code unterstützt (z. B.bytes | bytearray | memoryview).ByteStringwar ursprünglich als abstrakte Klasse gedacht, die als Obertyp für sowohlbytesals auchbytearraydienen sollte. Da die ABC jedoch nie Methoden hatte, war das Wissen, dass ein Objekt eine Instanz vonByteStringwar, nie wirklich nützlich über das Objekt. Andere gängige Puffertypen wiememoryviewwurden auch nie als Untertypen vonByteStringverstanden (weder zur Laufzeit noch von statischen Typprüfern).Weitere Einzelheiten finden Sie in PEP 688.
Seit Version 3.9 veraltet, wird in Version 3.17 entfernt.
- class typing.Collection(Sized, Iterable[T_co], Container[T_co])¶
Veralteter Alias für
collections.abc.Collection.Hinzugefügt in Version 3.6.
Seit Version 3.9 veraltet:
collections.abc.Collectionunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Container(Generic[T_co])¶
Veralteter Alias für
collections.abc.Container.Seit Version 3.9 veraltet:
collections.abc.Containerunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]])¶
Veralteter Alias für
collections.abc.ItemsView.Seit Version 3.9 veraltet:
collections.abc.ItemsViewunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.KeysView(MappingView, AbstractSet[KT_co])¶
Veralteter Alias für
collections.abc.KeysView.Seit Version 3.9 veraltet:
collections.abc.KeysViewunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Mapping(Collection[KT], Generic[KT, VT_co])¶
Veralteter Alias für
collections.abc.Mapping.Seit Version 3.9 veraltet:
collections.abc.Mappingunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.MappingView(Sized)¶
Veralteter Alias für
collections.abc.MappingView.Seit Version 3.9 veraltet:
collections.abc.MappingViewunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.MutableMapping(Mapping[KT, VT])¶
Veralteter Alias für
collections.abc.MutableMapping.Seit Version 3.9 veraltet:
collections.abc.MutableMappingunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.MutableSequence(Sequence[T])¶
Veralteter Alias für
collections.abc.MutableSequence.Seit Version 3.9 veraltet:
collections.abc.MutableSequenceunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.MutableSet(AbstractSet[T])¶
Veralteter Alias für
collections.abc.MutableSet.Seit Version 3.9 veraltet:
collections.abc.MutableSetunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Sequence(Reversible[T_co], Collection[T_co])¶
Veralteter Alias für
collections.abc.Sequence.Seit Version 3.9 veraltet:
collections.abc.Sequenceunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.ValuesView(MappingView, Collection[_VT_co])¶
Veralteter Alias für
collections.abc.ValuesView.Seit Version 3.9 veraltet:
collections.abc.ValuesViewunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
Aliase zu asynchronen ABCs in collections.abc¶
- class typing.Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType])¶
Veralteter Alias für
collections.abc.Coroutine.Siehe Annotating generators and coroutines für Details zur Verwendung von
collections.abc.Coroutineundtyping.Coroutinein Typannotationen.Hinzugefügt in Version 3.5.3.
Seit Version 3.9 veraltet:
collections.abc.Coroutineunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType])¶
Veralteter Alias für
collections.abc.AsyncGenerator.Siehe Annotating generators and coroutines für Details zur Verwendung von
collections.abc.AsyncGeneratorundtyping.AsyncGeneratorin Typannotationen.Hinzugefügt in Version 3.6.1.
Seit Version 3.9 veraltet:
collections.abc.AsyncGeneratorunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.Seit Version 3.13 geändert: Der Parameter
SendTypehat jetzt einen Standardwert.
- class typing.AsyncIterable(Generic[T_co])¶
Veralteter Alias für
collections.abc.AsyncIterable.Hinzugefügt in Version 3.5.2.
Seit Version 3.9 veraltet:
collections.abc.AsyncIterableunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.AsyncIterator(AsyncIterable[T_co])¶
Veralteter Alias für
collections.abc.AsyncIterator.Hinzugefügt in Version 3.5.2.
Seit Version 3.9 veraltet:
collections.abc.AsyncIteratorunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Awaitable(Generic[T_co])¶
Veralteter Alias für
collections.abc.Awaitable.Hinzugefügt in Version 3.5.2.
Seit Version 3.9 veraltet:
collections.abc.Awaitableunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
Aliase zu anderen ABCs in collections.abc¶
- class typing.Iterable(Generic[T_co])¶
Veralteter Alias für
collections.abc.Iterable.Seit Version 3.9 veraltet:
collections.abc.Iterableunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Iterator(Iterable[T_co])¶
Veralteter Alias für
collections.abc.Iterator.Seit Version 3.9 veraltet:
collections.abc.Iteratorunterstützt jetzt Indizierung ([]). Siehe PEP 585 und Generic Alias Type.
- typing.Callable¶
Veraltete Alias für
collections.abc.Callable.Siehe Annotating callable objects für Details zur Verwendung von
collections.abc.Callableundtyping.Callablein Typ-Annotationen.Veraltet seit Version 3.9:
collections.abc.Callableunterstützt jetzt Subskriptionen ([]). Siehe PEP 585 und Generic Alias Type.Geändert in Version 3.10:
Callableunterstützt jetztParamSpecundConcatenate. Siehe PEP 612 für weitere Details.
- class typing.Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType])¶
Veraltete Alias für
collections.abc.Generator.Siehe Annotating generators and coroutines für Details zur Verwendung von
collections.abc.Generatorundtyping.Generatorin Typ-Annotationen.Veraltet seit Version 3.9:
collections.abc.Generatorunterstützt jetzt Subskriptionen ([]). Siehe PEP 585 und Generic Alias Type.Geändert in Version 3.13: Standardwerte für die Send- und Rückgabetypen wurden hinzugefügt.
- class typing.Hashable¶
Veraltete Alias für
collections.abc.Hashable.Veraltet seit Version 3.12: Verwenden Sie stattdessen direkt
collections.abc.Hashable.
- class typing.Reversible(Iterable[T_co])¶
Veraltete Alias für
collections.abc.Reversible.Veraltet seit Version 3.9:
collections.abc.Reversibleunterstützt jetzt Subskriptionen ([]). Siehe PEP 585 und Generic Alias Type.
- class typing.Sized¶
Veraltete Alias für
collections.abc.Sized.Veraltet seit Version 3.12: Verwenden Sie stattdessen direkt
collections.abc.Sized.
Aliase für contextlib ABCs¶
- class typing.ContextManager(Generic[T_co, ExitT_co])¶
Veraltete Alias für
contextlib.AbstractContextManager.Der erste Typparameter,
T_co, repräsentiert den Typ, der von der Methode__enter__()zurückgegeben wird. Der optionale zweite Typparameter,ExitT_co, der standardmäßigbool | Noneist, repräsentiert den Typ, der von der Methode__exit__()zurückgegeben wird.Hinzugefügt in Version 3.5.4.
Veraltet seit Version 3.9:
contextlib.AbstractContextManagerunterstützt jetzt Subskriptionen ([]). Siehe PEP 585 und Generic Alias Type.Geändert in Version 3.13: Der optionale zweite Typparameter
ExitT_cowurde hinzugefügt.
- class typing.AsyncContextManager(Generic[T_co, AExitT_co])¶
Veraltete Alias für
contextlib.AbstractAsyncContextManager.Der erste Typparameter,
T_co, repräsentiert den Typ, der von der Methode__aenter__()zurückgegeben wird. Der optionale zweite Typparameter,AExitT_co, der standardmäßigbool | Noneist, repräsentiert den Typ, der von der Methode__aexit__()zurückgegeben wird.Hinzugefügt in Version 3.6.2.
Veraltet seit Version 3.9:
contextlib.AbstractAsyncContextManagerunterstützt jetzt Subskriptionen ([]). Siehe PEP 585 und Generic Alias Type.Geändert in Version 3.13: Der optionale zweite Typparameter
AExitT_cowurde hinzugefügt.
Zeitplan für die Veralterung wichtiger Funktionen¶
Bestimmte Funktionen in typing sind veraltet und könnten in einer zukünftigen Python-Version entfernt werden. Die folgende Tabelle fasst wichtige Veralterungen zur Bequemlichkeit zusammen. Dies kann sich ändern, und nicht alle Veralterungen sind aufgeführt.
Funktion |
Veraltet in |
Geplante Entfernung |
PEP/Ausgabe |
|---|---|---|---|
|
3.9 |
Unentschieden (siehe Veraltete Aliase für weitere Informationen) |
|
3.9 |
3.17 |
||
3.11 |
Unentschieden |
||
3.12 |
Unentschieden |
||
3.12 |
Unentschieden |
||
3.13 |
3.15 |
||
3.13 |
3.18 |