Escriba insinuando una lista de un tipo específico

128

Usando las anotaciones de funciones de Python 3, ¿es posible especificar el tipo de elementos contenidos en una lista homogénea (u otra colección) con el propósito de hacer sugerencias de tipo en PyCharm y otros IDE?

Un ejemplo de código pseudo-python para una lista de int:

def my_func(l:list<int>):
    pass

Sé que es posible usar Docstring ...

def my_func(l):
    """
    :type l: list[int]
    """
    pass

... pero prefiero el estilo de anotación si es posible.

Eric W.
fuente
¿Ha intentado utilizar el mismo formato en las anotaciones de funciones? ¿Que pasó?
jonrsharpe
@jonrsharpe Debería generar un error porque type object is not subscriptableal definir la función. Obviamente, puede usar una cadena: def my_func(L: 'list[int]')pero no sé si PyCharm lo analizará mientras analiza las cadenas de documentos ...
Bakuriu
@Bakuriu sí, quise decir 'list[int]', disculpas si eso no estaba claro.
jonrsharpe
No parece que PyCharm lo analice como lo hace con las cadenas de documentos.
Eric W.

Respuestas:

161

Respondiendo a mi propia pregunta; la respuesta del TLDR es No .

Actualización 2

En septiembre de 2015, se lanzó Python 3.5 con soporte para Type Hints e incluye un nuevo módulo de mecanografía . Esto permite la especificación de tipos contenidos dentro de colecciones. En noviembre de 2015, JetBrains PyCharm 5.0 es totalmente compatible con Python 3.5 para incluir sugerencias de tipo como se ilustra a continuación.

Completar código PyCharm 5.0 usando sugerencias de tipo

Actualización 1

En mayo de 2015, se aceptó formalmente PEP0484 (Type Hints) . El borrador de la implementación también está disponible en github en ambv / typehinting .

Respuesta original

A partir de agosto de 2014, he confirmado que no es posible usar anotaciones de tipo Python 3 para especificar tipos dentro de colecciones (por ejemplo, una lista de cadenas).

El uso de cadenas de documentos formateadas como reStructuredText o Sphinx son alternativas viables y están respaldadas por varios IDE.

También parece que Guido está reflexionando sobre la idea de extender las anotaciones de tipo en el espíritu de mypy: http://mail.python.org/pipermail/python-ideas/2014-August/028618.html

Eric W.
fuente
Actualización: parece que la sugerencia de tipos para incluir soporte para tipos genéricos ha llegado a PEP484 python.org/dev/peps/pep-0484
Eric W.
74

Ahora que Python 3.5 está oficialmente disponible, existe el módulo de soporte de Type Hints, typingy el correspondienteList "tipo" para los contenedores genéricos.

En otras palabras, ahora puede hacer:

from typing import List

def my_func(l: List[int]):
    pass
Alecxe
fuente
10

Se han agregado comentarios de tipo desde PEP 484

from . import Monitor
from typing import List, Set, Tuple, Dict


active_monitors = [] # type: List[Monitor]
# or
active_monitors: List[Monitor] = []

# bonus
active_monitors: Set[Monitor] = set()
monitor_pair: Tuple[Monitor, Monitor] = (Monitor(), Monitor())
monitor_dict: Dict[str, Monitor] = {'codename': Monitor()}

# nested
monitor_pair_list: List[Dict[str, Monitor]] = [{'codename': Monitor()}]

Esto me funciona actualmente en PyCharm con Python 3.6.4

Imagen de ejemplo en Pycharm

CoreCreatives
fuente
4

Con el apoyo de BDFL, ahora es casi seguro que Python (probablemente 3.5) proporcionará una sintaxis estandarizada para sugerencias de tipo a través de anotaciones de funciones.

https://www.python.org/dev/peps/pep-0484/

Como se menciona en el PEP, hay un verificador de tipo experimental (algo así como pylint, pero para tipos) llamado mypy que ya usa este estándar y no requiere ninguna sintaxis nueva.

http://mypy-lang.org/

Brendan Abel
fuente
3

A partir de Python 3.9, los tipos incorporados son genéricos con respecto a las anotaciones de tipos (consulte PEP 585 ). Esto permite especificar directamente el tipo de elementos:

def my_func(l: list[int]):
    pass

Varias herramientas pueden admitir esta sintaxis antes de Python 3.9. Cuando las anotaciones no se inspeccionan en tiempo de ejecución, la sintaxis es válida usando comillas o __future__.annotations.

# quoted
def my_func(l: 'list[int]'):
    pass
# postponed evaluation of annotation
from __future__ import annotations

def my_func(l: list[int]):
    pass
MisterMiyagi
fuente