tipos - str en python
Sugerencias sobre el tipo Python: ¿cómo saber si X es una subclase para Foo? (2)
¿Cómo debo escribir una sugerencia de tipo para los tipos de clase en Python? Considere este código:
class A(object):
pass
class B(A):
pass
def register(cls: type[A]):
assert issubclass(cls, A)
register(A)
register(B)
¿Es el type[A]
la forma correcta de escribir esto? Si solo usara cls: A
significaría que cls
es una instancia de A
, pero quiero decir que cls
es una clase / tipo, que al menos las subclases A
Específicamente, lo que quiero indicar es que el parámetro debe ser un tipo de modelo Django.
Para resolver su caso general, tendría que escribir una metaclase con un __subclasscheck__
adecuado. Posible, pero engorroso.
En su caso específico de clases de modelo de Django, ya existe una metaclase explícita, por lo que debe anotar que debería hacer el trabajo:
import django.db.model as model
def register(cls: model.base.ModelBase): ...
Esto funcionará porque isinstance(models.Model, models.base.ModelBase)
es verdadero.
Parece que otras respuestas actuales (22 de septiembre de 2016) aquí son incorrectas. Según PEP 484 (acerca de las sugerencias de tipo), existe una sugerencia para el tipo de objetos de clase, llamada Type[C] . Y de acuerdo con la documentación del módulo de typing
, puede utilizar la typing.Type[C] para lograr exactamente lo que desea. Los estoy usando con Python 3.5.2.
Citando Type[C] :
A veces desea hablar sobre objetos de clase, en particular objetos de clase que heredan de una clase dada. Esto se puede escribir como Tipo [C] donde C es una clase. Para aclarar: mientras C (cuando se usa como una anotación) se refiere a instancias de la clase C, el Tipo [C] se refiere a las subclases de C.
Y citando typing.Type[C] :
Una variable anotada con C puede aceptar un valor de tipo C. Por el contrario, una variable anotada con Tipo [C] puede aceptar valores que son clases en sí, específicamente, aceptará la clase objeto de C.
Y refiriéndose a su ejemplo específico:
import typing
class A(object):
pass
class B(A):
pass
def register(cls: typing.Type[A]):
assert issubclass(cls, A)
register(A)
register(B)
Puede verificar dicho código de forma estática usando mypy , y debería funcionar en casos simples. Tenga cuidado, sin embargo, que mypy es un trabajo en progreso. A partir de ahora, hay varias cuestiones abiertas sobre las sugerencias de tipo [C].