¿Cómo determino el tipo de una anotación de tipo Python en tiempo de ejecución?
Quiero inspeccionar la anotación de tipo de una variable de clase, y si es un typing.Literal
, extraer el valor literal y hacer algo con él. Pero:
from typing import Literal
class Foo:
bar: Literal['baz']
l = Foo.__annotations__['bar']
isinstance(l, Literal)
produce:
Error de seguimiento (última llamada más reciente):
Archivo "<stdin>", línea 1, in <module>
Archivo "/Users/tbabb/.pyenv/versions/3.8.5/lib/python3.8/typing.py", línea 342, in __instancecheck__
raise TypeError(f"{self} no se puede usar con isinstance()")
TypeError: typing.Literal no se puede usar con isinstance()
Además, l.__class__ == Literal
es False
, por lo que eso tampoco funciona.
¿Por qué no tiene éxito la comprobación de isinstance()
? ¿Cómo puedo comprobar el tipo de anotación que se está utilizando?
davy.ai
La comprobación
isinstance()
no tiene éxito porquetyping.Literal
intencionalmente no funciona con las comprobaciones deisinstance()
. Esto se debe a quetyping.Literal
es un tipo especial que se utiliza para valores literales, no clases, por lo que no debe tratarse como una clase para fines de comprobación de tipo.Para comprobar el tipo de anotación que se está utilizando, puedes utilizar las funciones
typing.get_origin()
ytyping.get_args()
. Por ejemplo, para comprobar si una variable de clase es de tipotyping.Literal
y extraer el valor literal de ella, puedes hacer lo siguiente:Aquí,
get_origin(l)
devolveráLiteral
sil
es untyping.Literal
, yget_args(l)
devolverá una tupla que contiene el/los valor(es) literal(es) sil
es untyping.Literal
.