es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La comprobación isinstance() no tiene éxito porque typing.Literal intencionalmente no funciona con las comprobaciones de isinstance(). Esto se debe a que typing.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() y typing.get_args(). Por ejemplo, para comprobar si una variable de clase es de tipo typing.Literal y extraer el valor literal de ella, puedes hacer lo siguiente:

    from typing import Literal, get_origin, get_args
    
    class Foo:
        bar: Literal['baz']
    
    l = Foo.__annotations__['bar']
    if get_origin(l) == Literal:
        literal_value = get_args(l)[0]
        # Haz algo con literal_value
    

    Aquí, get_origin(l) devolverá Literal si l es un typing.Literal, y get_args(l) devolverá una tupla que contiene el/los valor(es) literal(es) si l es un typing.Literal.

Comments are closed.