Python Language
Tipo de sugerencias
Buscar..
Sintaxis
- typing.Callable [[int, str], None] -> def func (a: int, b: str) -> None
- escribiendo.Mapping [str, int] -> {"a": 1, "b": 2, "c": 3}
- escribiendo.Lista [int] -> [1, 2, 3]
- escribiendo.configurar [int] -> {1, 2, 3}
- escribiendo.Opcional [int] -> Ninguno o int
- escribiendo.Secuencia [int] -> [1, 2, 3] o (1, 2, 3)
- escribiendo.cualquier -> cualquier tipo
- escribiendo.Union [int, str] -> 1 o "1"
- T = escribiendo.TypeVar ('T') -> Tipo genérico
Observaciones
La sugerencia de tipo, tal como se especifica en PEP 484
, es una solución formalizada para indicar de forma estática el tipo de valor para el Código Python. Al aparecer junto al módulo de typing
, las sugerencias de tipo ofrecen a los usuarios de Python la capacidad de anotar su código, ayudando así a los verificadores de tipos, mientras que, de forma indirecta, documentan su código con más información.
Tipos genéricos
El typing.TypeVar
es una fábrica de tipo genérico. Su objetivo principal es servir como parámetro / marcador de posición para las anotaciones genéricas de función / clase / método:
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]
Añadiendo tipos a una función
Tomemos un ejemplo de una función que recibe dos argumentos y devuelve un valor que indica su suma:
def two_sum(a, b):
return a + b
Al observar este código, uno no puede indicar de forma segura y sin duda el tipo de argumentos para la función two_sum
. Funciona tanto cuando se suministra con valores int
:
print(two_sum(2, 1)) # result: 3
y con cuerdas:
print(two_sum("a", "b")) # result: "ab"
y con otros valores, como list
s, tuple
s etcétera.
Debido a esta naturaleza dinámica de los tipos de python, donde muchos son aplicables para una operación determinada, cualquier verificador de tipo no podría afirmar razonablemente si una llamada para esta función debería permitirse o no.
Para ayudar a nuestro verificador de tipos, ahora podemos proporcionarle sugerencias de tipo en la definición de función que indica el tipo que permitimos.
Para indicar que solo queremos permitir tipos int
, podemos cambiar nuestra definición de función para que se vea así:
def two_sum(a: int, b: int):
return a + b
Las anotaciones siguen al nombre del argumento y están separadas por un carácter :
.
De forma similar, para indicar que solo se permiten los tipos str
, cambiaríamos nuestra función para especificarlo:
def two_sum(a: str, b: str):
return a + b
Además de especificar el tipo de los argumentos, también se podría indicar el valor de retorno de una llamada de función. Esto se hace agregando el carácter ->
seguido del tipo después del paréntesis de cierre en la lista de argumentos pero antes de :
al final de la declaración de la función:
def two_sum(a: int, b: int) -> int:
return a + b
Ahora hemos indicado que el valor de retorno al llamar a two_sum
debe ser de tipo int
. De manera similar, podemos definir valores apropiados para str
, float
, list
, set
y otros.
Aunque las sugerencias de tipo son utilizadas principalmente por los verificadores de tipo y los IDE, a veces es posible que necesite recuperarlos. Esto se puede hacer usando el __annotations__
especial __annotations__
:
two_sum.__annotations__
# {'a': <class 'int'>, 'b': <class 'int'>, 'return': <class 'int'>}
Miembros de la clase y métodos
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))
La referencia hacia adelante de la clase actual es necesaria ya que las anotaciones se evalúan cuando se define la función. Las referencias directas también se pueden usar cuando se hace referencia a una clase que causaría una importación circular si se importara.
Variables y atributos
Las variables son anotadas usando comentarios:
x = 3 # type: int
x = negate(x)
x = 'a type-checker might catch this error'
A partir de Python 3.6, también hay una nueva sintaxis para las anotaciones de variables . El código de arriba podría usar el formulario
x: int = 3
A diferencia de los comentarios, también es posible simplemente agregar una sugerencia de tipo a una variable que no se declaró anteriormente, sin establecer un valor para ella:
y: int
Además, si se utilizan en el módulo o en el nivel de clase, las sugerencias de tipo se pueden recuperar utilizando 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'>}, {})
Alternativamente, se puede acceder a ellos usando el atributo o variable especial __annotations__
:
x: int
print(__annotations__)
# {'x': <class 'int'>}
class C:
s: str
print(C.__annotations__)
# {'s': <class 'str'>}
NamedTuple
La creación de una doble con nombre con sugerencias de tipo se realiza utilizando la función NamedTuple del módulo de typing
:
import typing
Point = typing.NamedTuple('Point', [('x', int), ('y', int)])
Tenga en cuenta que el nombre del tipo resultante es el primer argumento de la función, pero debe asignarse a una variable con el mismo nombre para facilitar el trabajo de los verificadores de tipos.
Escriba sugerencias para argumentos de palabras clave
def hello_world(greeting: str = 'Hello'):
print(greeting + ' world!')
Tenga en cuenta los espacios alrededor del signo igual en contraposición a la forma en que se suelen diseñar los argumentos de palabras clave.