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

Classe e métodos ABSTRATOS em Python 3

Olá, Estou fazendo o curso com python3 e na aula que implementou-se o Template Method eu notei que as classes abstratas e métodos abstratos não funcionaram.

Ou seja, mesmo com a annotation @abstractmethod, a implementação da Herança e a AUSÊNCIA da implementação dos métodos abstratos nas classes herdeiras, o compilador do python3 executa normalmente o código. MAS o python 2 exibe o erro. Veja o código e os resultados logo abaixo:

CÓDIGO - Impostos

# -*- coding: UTF-8 -*-
from abc import ABCMeta, abstractmethod

class Template_de_imposto_condicional(object):
    ##TORNA A CLASSE ABSTRACT
    __metaclass__ = ABCMeta

    def calcula(self, orcamento):
        if self.deve_usar_maxima_taxacao(orcamento):
            return self.maxima_taxacao(orcamento)
        else:
            return self.minima_taxacao(orcamento)

    @abstractmethod
    def deve_usar_maxima_taxacao(self, orcamento):
        pass

    @abstractmethod
    def maxima_taxacao(self, orcamento):
        pass

    @abstractmethod
    def minima_taxacao(self, orcamento):
        pass


class ISS(object):
    def calcula(self, orcamento):
        return orcamento.valor * 0.1


class ICMS(object):
    def calcula(self, orcamento):
        return orcamento.valor * 0.06


class IPTU(Template_de_imposto_condicional):
    def calcula(self, orcamento):
        if orcamento.valor > 500:
            return orcamento.valor * 0.07
        return orcamento.valor * 0.05


class IPVA(Template_de_imposto_condicional):

    def calcula(self, orcamento):
        if orcamento.valor > 500 and self.__tem_item_maior_que_100(orcamento):
            return orcamento.valor * 0.1
        else:
            return orcamento.valor * 0.06

    def __tem_item_maior_que_100(orcamento):
        for item in orcamento.obter_itens():
            if item.valor > 100:
                return True
        return False

CÓDIGO - Calculador

# -*- coding: UTF-8 -*-

from impostos import ICMS, ISS, IPTU, IPVA

class CalculadorDeImpostos:

    def realiza_calculo(self, orcamento, imposto):
        imposto_calculado = imposto.calcula(orcamento)
        return imposto_calculado

if __name__ == '__main__':
    from orcamento import Orcamento
    from item import Item

    calculador = CalculadorDeImpostos()

    orcamento = Orcamento()
    orcamento.adiciona_item(Item('Item - 1', 200.0))
    # orcamento.adiciona_item(Item('Item - 4', 250.0))
    orcamento.adiciona_item(Item('Item - 4', 250.0))

    print('ICMS: ', calculador.realiza_calculo(orcamento, ICMS()))
    print('ISS: ', calculador.realiza_calculo(orcamento, ISS()))
    print('IPTU: ', calculador.realiza_calculo(orcamento, IPTU()))
    print('IPVA: ', calculador.realiza_calculo(orcamento, IPVA()))

RESULTADO - Python 3

/usr/bin/python3 /home/joseavanijr/dev/cursos/curso_alura_design_patterns_01/templateMethod/calcularoDeImpostos.py
ICMS:  27.0
ISS:  45.0
IPTU:  22.5
IPVA:  27.0

Process finished with exit code 0

RESULTADO - Python 2

~/d/c/c/templateMethod ❯❯❯ python2 calcularoDeImpostos.py

('ICMS: ', 27.0)
('ISS: ', 45.0)
Traceback (most recent call last):
  File "calcularoDeImpostos.py", line 27, in <module>
    print('IPTU: ', calculador.realiza_calculo(orcamento, IPTU()))
TypeError: Can't instantiate abstract class IPTU with abstract methods deve_usar_maxima_taxacao, maxima_taxacao, minima_taxacao

PROTANTO, como faço classes e métodos abstratos em python3?

1 resposta
solução!

No python 3 voce deve fazer um pouco diferente, herdando a classe ABCMeta:

class A(object, metaclass=ABCMeta):
    @abstractmethod
    def x(self):
        pass