1
resposta

Como usar typing.Union para tipar um atributo que pode ser duas ou mais, classes/funções

Bom dia,

minha dúvida é a respeito do uso de typing. Gostaria de aplicar o Union para tipar o atributo imposto da def realiza_calculo.

Este atributo pode receber duas funções que foram importadas (from impostos import calcula_ICMS, calcula_ISS)

Coloquei o Union em uma variável function_imp (function_imp = Union[calcula_ICMS, calcula_ISS])

Posteriormente realizei a tipagem na def realiza_calculo

def realiza_calculo(self, orçamento: Orcamento, imposto: function_imp) -> None:

from typing import Union
from orcamento import Orcamento
from impostos import calcula_ICMS, calcula_ISS

function_imp = Union[calcula_ICMS, calcula_ISS]


class Calculador_de_impostos(object):

    def realiza_calculo(
        self, orçamento: Orcamento, imposto: function_imp
    ) -> None:

        imposto_calculado: Union[int, float] = 0

        imposto_calculado = imposto(orçamento)

        print(imposto_calculado)

Dai recebo alguns erros:


Function "impostos.calcula_ICMS" is not valid as a type

Function "impostos.calcula_ISS" is not valid as a type

calcula_ICMS? not callable

calcula_ISS? not callable

Perhaps you need "Callable[...]" or a callback protocol?

Por fim a duvida é como usar Union para tipar um atributo que pode ser duas ou mais, classes ou funções.

Gosto da ideia de que 3 meses irei retornar ao meu código para trabalhar em uma manutenção, ou implementar uma melhoria e poder ver o que são os atributos e as saídas das funções, isso facilita demais a vida, rs.

Desde já agradeço a ajuda.

Obrigado.

1 resposta

Olá Livio, tudo bem com você?

Peço desculpas pela demora no retorno.

O uso do Union deverá ser feito para união de tipos nativos do python, como por exemplo int, str entre outros, não podendo ser utilizado os que não são nativos, como as funções calcula_ISS e calcula_ICMS.

Os erros apresentados estão acontecendo devido ao uso do Union na dica de tipo para duas funções e não para dois tipos.

Para que sejam corrigidos os erros, devemos fazer o uso da dica de tipo Callable e o tipo Any. A dica de tipo Callable será utilizada para informar que o atributo imposto recebe um valor que pode ser chamado, como a dica de tipo não aceita que seja informado diretamente funções, vamos informar que o atributo imposto recebe o tipo Any como entrada.

A sintaxe de uso da dica de tipo Callable é a seguinte:

  • Callable[[tipo_de_entrada], tipo_de_ retorno]

Código

from typing import Callable, Any
function_imp = Callable[[Any], float]

Realizando as mudanças na declaração de tipo, basta realizar o teste do código com o uso do Mypy.

Para aprimorar ainda mais o seu conhecimento sobre dicas de tipos, recomendo a leitura do seguinte artigo, onde apresenta os modos de uso das dicas de tipos e as principais ferramentas para verificação dos arquivos.

O artigo acima está em inglês, caso tenha dificuldades com o idioma, recomendo o uso do tradutor do navegador.

Fico à disposição em caso de dúvidas.

Abraços e bons estudos.

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!