Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Erro mypy por conta da classe FabricaFila

Após a implementação do Design Pattern Factory através da criação da classe FabricaFila o mypy passou a acusar um erro no arquivo main.py, apesar do mypy acusar esse erro o código funciona sem nenhum problema, gostaria de saber se possui alguma forma de corrigir o problema sem ser retirando o Type Hinting de retorno da classe FabricaFila.

Erro acusado:

main.py:21: error: Item "FilaNormal" of "Union[FilaNormal, FilaPrioritaria]" has no attribute "estatistica"
main.py:22: error: Item "FilaNormal" of "Union[FilaNormal, FilaPrioritaria]" has no attribute "estatistica"
Found 2 errors in 1 file (checked 1 source file)

Arquivo fabrica_fila.py:

from typing import Union

from fila_normal import FilaNormal
from fila_prioritaria import FilaPrioritaria
from constantes import TIPO_FILA_NORMAL, TIPO_FILA_PRIORITARIA


class FabricaFila:

    @staticmethod
    def pega_fila(tipo_fila: str) -> Union[FilaNormal, FilaPrioritaria]:
        if tipo_fila == TIPO_FILA_NORMAL:
            return FilaNormal()
        elif tipo_fila == TIPO_FILA_PRIORITARIA:
            return FilaPrioritaria()
        else:
            raise NotImplementedError('O tipo de fila solicitado não existe')

Arquivo main.py

from fabrica_fila import FabricaFila
from estatistica_resumida import EstatisticaResumida
from estatistica_detalhada import EstatisticaDetalhada
from constantes import TIPO_FILA_NORMAL, TIPO_FILA_PRIORITARIA


fila_teste = FabricaFila.pega_fila(TIPO_FILA_NORMAL)
fila_teste.atualiza_fila()
fila_teste.atualiza_fila()
fila_teste.atualiza_fila()
print(fila_teste.chama_cliente(5))
print(fila_teste.chama_cliente(10))


fila_teste_2 = FabricaFila.pega_fila(TIPO_FILA_PRIORITARIA)
fila_teste_2.atualiza_fila()
fila_teste_2.atualiza_fila()
fila_teste_2.atualiza_fila()
print(fila_teste_2.chama_cliente(10))
print(fila_teste_2.chama_cliente(1))
print(fila_teste_2.estatistica(EstatisticaResumida('10/01/1993', 196)))
print(fila_teste_2.estatistica(EstatisticaDetalhada('10/01/1993', 196)))
1 resposta
solução!

Oi Francisco, tudo bem?

O erro: Item "FilaNormal" of "Union[FilaNormal, FilaPrioritaria]" has no attribute "estatistica", ocorre porque a classe "FilaNormal" não tem o método estatística. E por mais que você chame no método pega_fila a fila prioritária, tudo que o mypy sabe é que você retorna uma FilaNormal ou uma FilaPrioritaria, e ele verá que na classe de FilaNormal não possui o método estatística. Porém, na main você o chama:

print(fila_teste_2.estatistica(EstatisticaResumida('10/01/1993', 196)))

Ele não tem controle de qual método que foi de fato retornado ali, sabe que foi um ou outro e que em um deles, o método estatística não existe.

Isso acontece porque estamos retornando dois tipos em uma função e isso muita das vezes não é recomendado, é interessante que retornemos apenas um único tipo de dado.

Então, o que você poderia fazer é retornar uma tupla por exemplo :

  • Algo como:
 def pega_fila(tipo_fila) -> Tuple:
        if tipo_fila == TIPO_FILA_NORMAL:
            return (FilaNormal(),)
        elif tipo_fila == TIPO_FILA_PRIORITARIA:
           return (FilaPrioritaria(),)
        else:
            raise NotImplementedError('Tipo de fila não existe')

E na main, acessar pelo índice. Exemplo:

teste_fabrica = FabricaFila.pega_fila('prioritaria')
teste_fabrica[0].atualiza_fila()

Dessa maneira, retornarmos apenas um único tipo de dado. Você também pode aderir ao uso de dosctrings para dizer o que aquela função faz, quais parâmetros recebe e o quê irá retornar. Deixo abaixo um material sobre dosctring:

Qualquer dúvida estou a disposição. Abraços e bons estudos!