Python Language
Type Tips
Zoeken…
Syntaxis
- typing.Callable [[int, str], None] -> def func (a: int, b: str) -> Geen
- typing.Mapping [str, int] -> {"a": 1, "b": 2, "c": 3}
- typing.List [int] -> [1, 2, 3]
- typing.Set [int] -> {1, 2, 3}
- typing.Optional [int] -> Geen of int
- typen. Equence [int] -> [1, 2, 3] of (1, 2, 3)
- typ.Any -> Elk type
- typing.Union [int, str] -> 1 of "1"
- T = typing.TypeVar ('T') -> Generiek type
Opmerkingen
Type Hinting, zoals gespecificeerd in PEP 484
, is een geformaliseerde oplossing om het type van een waarde voor Python Code statisch aan te geven. Door naast de typing
verschijnen, bieden type-hints Python-gebruikers de mogelijkheid om hun code te annoteren, waardoor typecontroles worden ondersteund en, indirect, hun code met meer informatie wordt gedocumenteerd.
Generieke typen
De typing.TypeVar
is een generieke typing.TypeVar
. Het primaire doel is om te dienen als parameter / tijdelijke aanduiding voor generieke functie / klasse / methode-annotaties:
import typing
T = typing.TypeVar("T")
def get_first_element(l: typing.Sequence[T]) -> T:
"""Gets the first element of a sequence."""
return l[0]
Typen toevoegen aan een functie
Laten we een voorbeeld nemen van een functie die twee argumenten ontvangt en een waarde retourneert die hun som aangeeft:
def two_sum(a, b):
return a + b
Door naar deze code te kijken, kan men niet veilig en zonder twijfel het type argumenten voor functie two_sum
. Het werkt beide wanneer het wordt voorzien van int
waarden:
print(two_sum(2, 1)) # result: 3
en met snaren:
print(two_sum("a", "b")) # result: "ab"
en met andere waarden, zoals list
s, tuple
s et cetera.
Vanwege deze dynamische aard van python-typen, waar veel van toepassing zijn voor een bepaalde bewerking, kan elk type checker niet redelijkerwijs beweren of een oproep voor deze functie moet worden toegestaan of niet.
Om onze typecontrole te helpen, kunnen we er nu typetips voor geven in de functiedefinitie die het type aangeeft dat we toestaan.
Om aan te geven dat we alleen int
typen willen toestaan, kunnen we onze functiedefinitie als volgt wijzigen:
def two_sum(a: int, b: int):
return a + b
Annotaties volgen de naam van het argument en worden gescheiden door een :
-teken.
Evenzo, om aan te geven dat alleen str
typen zijn toegestaan, zouden we onze functie wijzigen om het op te geven:
def two_sum(a: str, b: str):
return a + b
Naast het specificeren van het type argumenten, zou men ook de retourwaarde van een functieaanroep kunnen aangeven. Dit wordt gedaan door het teken ->
gevolgd door het type na het haakje sluiten in de lijst met argumenten maar vóór de :
aan het einde van de functieverklaring:
def two_sum(a: int, b: int) -> int:
return a + b
Nu hebben we aangegeven dat de retourwaarde bij het aanroepen van two_sum
van het type int
moet zijn. Op dezelfde manier kunnen we geschikte waarden definiëren voor str
, float
, list
, set
en andere.
Hoewel typetips meestal worden gebruikt door typecontroles en IDE's, moet u ze soms ophalen. Dit kan worden gedaan met behulp van het speciale kenmerk __annotations__
:
two_sum.__annotations__
# {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
Klasleden en methoden
class A:
x = None # type: float
def __init__(self, x: float) -> None:
"""
self should not be annotated
init should be annotated to return None
"""
self.x = x
@classmethod
def from_int(cls, x: int) -> 'A':
"""
cls should not be annotated
Use forward reference to refer to current class with string literal 'A'
"""
return cls(float(x))
Voorwaartse referentie van de huidige klasse is nodig omdat annotaties worden geëvalueerd wanneer de functie is gedefinieerd. Voorwaartse verwijzingen kunnen ook worden gebruikt bij het verwijzen naar een klasse die bij import een circulaire import zou veroorzaken.
Variabelen en attributen
Variabelen worden geannoteerd met opmerkingen:
x = 3 # type: int
x = negate(x)
x = 'a type-checker might catch this error'
Vanaf Python 3.6 is er ook een nieuwe syntaxis voor variabele annotaties . De bovenstaande code kan het formulier gebruiken
x: int = 3
In tegenstelling tot opmerkingen is het ook mogelijk om een typetip toe te voegen aan een variabele die niet eerder is gedeclareerd, zonder er een waarde voor in te stellen:
y: int
Als deze bovendien worden gebruikt in de module of het typing.get_type_hints(class_or_module)
worden opgehaald met typing.get_type_hints(class_or_module)
:
class Foo:
x: int
y: str = 'abc'
print(typing.get_type_hints(Foo))
# ChainMap({'x': <class 'int'>, 'y': <class 'str'>}, {})
Als alternatief kunnen ze worden geopend met behulp van de speciale variabele __annotations__
:
x: int
print(__annotations__)
# {'x': <class 'int'>}
class C:
s: str
print(C.__annotations__)
# {'s': <class 'str'>}
NamedTuple
Het creëren van een namedtuple met type hints wordt gedaan met behulp van de functie NamedTuple van de typing
module:
import typing
Point = typing.NamedTuple('Point', [('x', int), ('y', int)])
Merk op dat de naam van het resulterende type het eerste argument voor de functie is, maar het moet worden toegewezen aan een variabele met dezelfde naam om het werk van typecontroles te vergemakkelijken.
Typ hints voor trefwoordargumenten
def hello_world(greeting: str = 'Hello'):
print(greeting + ' world!')
Let op de spaties rond het isgelijkteken in tegenstelling tot hoe trefwoordargumenten meestal worden vormgegeven.