Pular para o conteúdo
Ramos da Informática - Comunidade de Desenvolvedores

Torne-se um desenvolvedor FullStack: Pacote completo de formação desenvolvedor Frontend e Backend utilizando as linguagens de programação e frameworks mais procurados no mercado de trabalho. Mais informações, aqui. Faça o download do E-BookGuia Completo Para Se Tornar um(a) Desenvolvedor(a) Full-Stack, Começando do ZERO”.

Engenheiro de Software, autor de livros sobe tecnologia e negócios. É mantenedor do site Ramos da Informática. Hobbies: investir em ações, natação e finanças.

Engenheiro de Software, autor de livros sobe tecnologia e negócios. É mantenedor do site Ramos da Informática. Hobbies: investir em ações, natação e finanças.

admin

Todos os artigos deste autor

Orientação a objetos de outra forma: ABC

Chatbots com Whatsapp e Cielo integrados Nesse curso, eu vou te mostrar como o consumidor poder realizar um pagamento por dentro do aplicativo do WhatsApp, aonde o seu cliente vai entrar numa conversa como entraria numa conversa com qualquer pessoa ou com a sua empresa, navegar entre os produtos/serviços em menus simples enviados pelo chatbot, adicionar esses produtos/serviços no carrinho de compras, e num determinado ponto do chat, um link exclusivo é enviado para o cliente preencher os dados do cartão de crédito. No final, a análise é devolvida para o Whatsapp no qual a conversa foi iniciada. Inscreva-se.

Na discussão sobre herança e mixins foram criadas várias classes, como Autenticavel e AutenticavelComRegistro que adicionam funcionalidades a outras classes e implementavam tudo o que precisavam para seu funcionamento. Entretanto podem existir casos em que não seja possível implementar todas as funções na própria classe, deixando com que as classes que a estende implemente essas funções. Uma forma de fazer isso é través da Orientação a objetos das ABC (abstract base classes, ou classes base abstratas).

Sem uso de classes base abstratas na orientação a objetos

Um exemplo de classe que não é possível implementar todas as funcionalidades foi dada no texto Encapsulamento da lógica do algoritmo, que discutia a leitura de valores do teclado até que um valor válido fosse lido (ou que repete a leitura caso um valor inválido tivesse sido informado). Nesse caso a classe ValidaInput implementava a lógica base de funcionamento, porém eram suas classes filhas (ValidaNomeInput e ValidaNotaInput) que implementavam as funções para tratar o que foi lido do teclado e verificar se é um valor válido ou não.

class ValidaInput:
mensagem_valor_invalido = ‘Valor inválido!’def ler_entrada(self, prompt):
return input(prompt)def transformar_entrada(self, entrada):
raise NotImplementedError

def validar_valor(self, valor):
raise NotImplementedError

def __call__(self, prompt):
while True:
try:
valor = self.transformar_entrada(self.ler_entrada(prompt))
if self.validar_valor(valor):
break
except ValueError:

print(self.mensagem_valor_invalido)
return valor

class ValidaNomeInput(ValidaInput):
mensagem_valor_invalido = ‘Nome inválido!’

def transformar_entrada(self, entrada):
return entrada.strip().title()

def validar_valor(self, valor):
return valor !=

class ValidaNotaInput(ValidaInput):
mensagem_valor_invalido = ‘Nota inválida!’

def transformar_entrada(self, entrada):
return float(entrada)

def validar_valor(self, valor):
return 0 <= valor <= 10

Entretanto, esse código permite a criação de objetos da classe ValidaInput mesmo sem ter uma implementação das funções transformar_entrada e validar_valor. E a única mensagem de erro ocorreria ao tentar executar essas funções, o que poderia estar longe do problema real, que é a criação de um objeto a partir de uma classe que não prove todas as implementações das suas funções, o que seria semelhante a uma classe abstrata em outras linguagens.

obj = ValidaInput()

# Diversas linhas de código

obj(‘Entrada: ‘) # Exceção NotImplementedError lançada

Com uso de classes base abstratas na orientação a objetos

Seguindo a documentação da ABC, para utilizá-las é necessário informar a metaclasse ABCMeta na criação da classe, ou simplesmente estender a classe ABC, e decorar com abstractmethod as funções que as classes que a estenderem deverão implementar. Exemplo:

from abc import ABC, abstractmethod

class ValidaInput(ABC):
mensagem_valor_invalido = ‘Valor inválido!’

def ler_entrada(self, prompt):
return input(prompt)

@abstractmethod
def transformar_entrada(self, entrada):

@abstractmethod
def validar_valor(self, valor):

def __call__(self, prompt):
while True:
try:
valor = self.transformar_entrada(self.ler_entrada(prompt))
if self.validar_valor(valor):
break
except ValueError:

print(self.mensagem_valor_invalido)
return valor

Desta forma, ocorrerá um erro já ao tentar criar um objeto do tipo ValidaInput, dizendo quais são as funções que precisam ser implementadas. Porém funcionará normalmente ao criar objetos a partir das classes ValidaNomeInput e ValidaNotaInput visto que elas implementam essas funções.

obj = ValidaInput() # Exceção TypeError lançada

nome_input = ValidaNomeInput() # Objeto criado
nota_input = ValidaNotaInput() # Objeto criado

Como essas funções não utilizam a referência ao objeto (self), ainda é possível decorar as funções com staticmethod, como:

from abc import ABC, abstractmethod

class ValidaInput(ABC):
mensagem_valor_invalido = ‘Valor inválido!’

@staticmethod
def ler_entrada(prompt):
return input(prompt)

@staticmethod
@abstractmethod
def transformar_entrada(entrada):

@staticmethod
@abstractmethod
def validar_valor(valor):

def __call__(self, prompt):
while True:
try:
valor = self.transformar_entrada(self.ler_entrada(prompt))
if self.validar_valor(valor):
break
except ValueError:

print(self.mensagem_valor_invalido)
return valor

class ValidaNomeInput(ValidaInput):
mensagem_valor_invalido = ‘Nome inválido!’

@staticmethod
def transformar_entrada(entrada):
return entrada.strip().title()

@staticmethod
def validar_valor(valor):
return valor !=

class ValidaNotaInput(ValidaInput):
mensagem_valor_invalido = ‘Nota inválida!’

@staticmethod
def transformar_entrada(entrada):
return float(entrada)

@staticmethod
def validar_valor(valor):
return 0 <= valor <= 10

Isso também seria válido para funções decoradas com classmethod, que receberiam a referência a classe (cls).

Considerações

Não é necessário utilizar ABC para fazer o exemplo discutido, porém ao utilizar essa biblioteca ficou mais explícito quais as funções que precisavam ser implementados nas classes filhas, ainda mais que sem utilizar ABC a classe base poderia nem ter as funções, com:

class ValidaInput:
mensagem_valor_invalido = ‘Valor inválido!’def ler_entrada(self, prompt):
return input(prompt)def __call__(self, prompt):
while True:
try:
valor = self.transformar_entrada(self.ler_entrada(prompt))
if self.validar_valor(valor):
break
except ValueError:

print(self.mensagem_valor_invalido)
return valor

Como Python possui duck-typing, não é necessário uma grande preocupação com os tipos, como definir e utilizar interfaces presentes em outras implementações de orientação a objetos, porém devido à herança múltipla, ABC pode ser utilizada como interface que não existe em Python, fazendo com que as classes implementem determinadas funções. Para mais a respeito desse assunto, recomendo as duas lives do dunossauro sobre ABC (1 e 2), e a apresentação do Luciano Ramalho sobre type hints.

Uma classe filha também não é obrigada a implementar todas as funções decoradas com abstractmethod, mas assim como a classe pai, não será possível criar objetos a partir dessa classe, apenas de uma classe filha dela que implemente as demais funções. Como se ao aplicar um abstractmethod tornasse a classe abstrata, e qualquer classe filha só deixasse de ser abstrata quando a última função decorada com abstractmethod for sobrescrita. Exemplo:

from abc import ABC, abstractmethod

class A(ABC):
@abstractmethod
def func1(self):

@abstractmethod
def func2(self):

class B(A):
def func1(self):
print(‘1’)

class C(B):
def func2(self):
print(‘2’)

a = A() # Erro por não implementar func1 e func2
b = B() # Erro por não implementar func2
c = C() # Objeto criado

Esse artigo foi publicado originalmente no meu blog, passe por lá, ou siga-me no DEV para ver mais artigos que eu escrevi.

Este artigo foi importado automaticamente por fazer parte do Planetário Dev. Quer fazer parte deste HUB de conteúdos? Faça parte do Planetário e veja as vantagens.

Não tem site ou blog? Seja um autor do site e ainda pode ser remunerado.

Mais sobre Newsletters?

32 melhores newsletters sobre negócios, startups e tecnologia para assinar em 2022

Leia também:

Facebook
LinkedIn
Twitter
Pinterest
Reddit
Telegram
WhatsApp
Email
Print

Relacionados

Deixe uma resposta