Pular para o conteúdo

Como usar a interface em Python?

[

Implementando uma Interface em Python

por William Murphy (avançado)

Interfaces desempenham um papel importante na engenharia de software. Conforme um aplicativo cresce, as atualizações e alterações na base de código se tornam mais difíceis de gerenciar. Na maioria das vezes, você acaba tendo classes que se parecem muito, mas são diferentes, o que pode levar a alguma confusão. Neste tutorial, você verá como pode usar uma interface em Python para ajudar a determinar qual classe usar para resolver o problema atual.

Neste tutorial, você será capaz de:

  • Entender como as interfaces funcionam e as ressalvas da criação de interfaces em Python.
  • Compreender o quão úteis são as interfaces em uma linguagem dinâmica como o Python.
  • Implementar uma interface informal em Python.
  • Utilizar abc.ABCMeta e @abc.abstractmethod para implementar uma interface formal em Python.

As interfaces em Python são tratadas de maneira diferente do que na maioria das outras linguagens e podem variar em complexidade de design. Ao final deste tutorial, você terá uma melhor compreensão de alguns aspectos do modelo de dados do Python, bem como de como as interfaces em Python se comparam às de linguagens como Java, C++ e Go.

Bônus Gratuito: Mastery Python, um curso gratuito para desenvolvedores Python que mostra a estratégia e a mentalidade que você precisará para levar suas habilidades em Python para o próximo nível.

Faça o Quiz: Teste seus conhecimentos com o nosso quiz interativo “Implementando uma Interface em Python”. Ao final, você receberá uma pontuação para acompanhar seu progresso de aprendizado ao longo do tempo.

Visão Geral da Interface em Python

Em alto nível, uma interface atua como um esboço para projetar classes. Assim como as classes, as interfaces definem métodos. No entanto, esses métodos são abstratos. Um método abstrato é aquele que a interface simplesmente define, não sendo implementado. Essa implementação é feita pelas classes, que então implementam a interface e dão um significado concreto aos métodos abstratos da interface.

A abordagem do Python para o design de interfaces é um pouco diferente em comparação com linguagens como Java, Go e C++. Todas essas linguagens têm uma palavra-chave interface, enquanto o Python não. O Python ainda difere de outras linguagens em outro aspecto. Ele não exige que a classe que está implementando a interface defina todos os métodos abstratos da interface.

Interfaces Informais

Em certas circunstâncias, você pode não precisar das regras rígidas de uma interface formal em Python. A natureza dinâmica do Python permite que você implemente uma interface informal. Uma interface informal em Python é uma classe que define métodos que podem ser sobrescritos, mas que não têm uma aplicação estrita.

class InformalParserInterface:
def load_data_source(self, path: str, file_name: str) -> str:
"""Carrega o arquivo para extrair o texto."""
pass
def extract_text(self, full_file_name: str) -> dict:
"""Extrai o texto do arquivo atualmente carregado."""
pass

A classe InformalParserInterface define dois métodos: .load_data_source() e .extract_text(). Esses métodos são abstratos, ou seja, eles não têm uma implementação específica dentro da interface. Eles servem apenas como um esboço do comportamento esperado pelas classes que implementam essa interface.

Ao implementar uma classe concreta que utilize essa interface informal, você precisará sobrescrever esses métodos e fornecer a implementação adequada. Por exemplo, você pode ter uma classe PdfParser:

class PdfParser(InformalParserInterface):
def load_data_source(self, path: str, file_name: str) -> str:
# Implementação específica para carregar um arquivo PDF
pass
def extract_text(self, full_file_name: str) -> dict:
# Implementação específica para extrair texto de um arquivo PDF
pass

Essa classe implementa a interface InformalParserInterface e fornece a implementação necessária para os métodos .load_data_source() e .extract_text().

Da mesma forma, você pode ter uma classe EmlParser que também implementa a interface InformalParserInterface, mas fornece uma implementação diferente para esses métodos:

class EmlParser(InformalParserInterface):
def load_data_source(self, path: str, file_name: str) -> str:
# Implementação específica para carregar um arquivo EML
pass
def extract_text(self, full_file_name: str) -> dict:
# Implementação específica para extrair texto de um arquivo EML
pass

No entanto, é importante ressaltar que, ao utilizar essa abordagem informal, não há nenhuma garantia de que as classes que implementam a interface irão realmente fornecer a implementação correta ou que seguirão o contrato da interface. É responsabilidade do desenvolvedor garantir que a implementação seja feita corretamente.

Interfaces Formais

Em algumas situações, você pode precisar de uma abordagem mais rigorosa em relação às interfaces em Python. Para isso, você pode utilizar uma interface formal. Em Python, a biblioteca abc fornece suporte para criar interfaces formais.

Uma interface formal é criada definindo uma classe base que herda de abc.ABC e, em seguida, utilizando o decorador @abc.abstractmethod para identificar os métodos abstratos da interface. Por exemplo:

import abc
class FormalParserInterface(metaclass=abc.ABCMeta):
@abc.abstractmethod
def load_data_source(self, path: str, file_name: str) -> str:
"""Carrega o arquivo para extrair o texto."""
pass
@abc.abstractmethod
def extract_text(self, full_file_name: str) -> dict:
"""Extrai o texto do arquivo atualmente carregado."""
pass

No exemplo acima, FormalParserInterface é a classe base que herda de abc.ABC e define os métodos abstratos .load_data_source() e .extract_text(). Graças ao uso do decorador @abc.abstractmethod, esses métodos são marcados como abstratos e sua implementação é deixada para as classes concretas que implementam essa interface.

Ao implementar uma classe concreta que utiliza essa interface formal, você precisará sobrescrever os métodos abstratos e fornecer a implementação adequada, assim como foi feito na abordagem informal. No entanto, a diferença aqui é que a biblioteca abc irá garantir que todos os métodos abstratos da interface sejam implementados corretamente.

Por exemplo, você pode ter uma classe PdfParser:

class PdfParser(FormalParserInterface):
def load_data_source(self, path: str, file_name: str) -> str:
# Implementação específica para carregar um arquivo PDF
pass
def extract_text(self, full_file_name: str) -> dict:
# Implementação específica para extrair texto de um arquivo PDF
pass

A classe PdfParser implementa a interface FormalParserInterface e fornece a implementação necessária para os métodos .load_data_source() e .extract_text(). A diferença é que, se você se esquecer de implementar algum desses métodos na classe concreta, o Python irá gerar um erro em tempo de execução.

Da mesma forma, você pode ter uma classe EmlParser que também implementa a interface FormalParserInterface, mas fornece uma implementação diferente para esses métodos:

class EmlParser(FormalParserInterface):
def load_data_source(self, path: str, file_name: str) -> str:
# Implementação específica para carregar um arquivo EML
pass
def extract_text(self, full_file_name: str) -> dict:
# Implementação específica para extrair texto de um arquivo EML
pass

Assim como na abordagem informal, ao utilizar a abordagem formal não há nenhuma garantia de que as classes que implementam a interface irão realmente fornecer a implementação correta ou que seguirão o contrato da interface. É responsabilidade do desenvolvedor garantir que a implementação seja feita corretamente.

Interfaces em Outras Linguagens

Embora Python tenha sua própria abordagem para o design de interfaces, é interessante analisar como interfaces são implementadas em outras linguagens. Aqui estão alguns exemplos:

  • Java: Em Java, as interfaces são criadas utilizando a palavra-chave interface e podem ser implementadas por várias classes. Todas as classes que implementam uma interface devem fornecer uma implementação para todos os métodos da interface.
  • C++: Em C++, as interfaces são criadas utilizando classes abstratas puras. Uma classe abstrata pura é uma classe que contém ao menos um método abstrato, que não possui uma implementação. As classes que herdam dessa classe abstrata pura devem fornecer uma implementação para todos os métodos abstratos.
  • Go: Go não possui um conceito de interfaces como em Java ou C++. Em vez disso, qualquer tipo pode implementar métodos e satisfazer um contrato específico. Dessa forma, qualquer tipo que implemente os métodos especificados pode ser considerado como satisfazendo uma interface.

Cada linguagem tem suas próprias características e abordagens em relação às interfaces. É sempre importante entender as diferenças para explorar as vantagens e desvantagens de cada abordagem.

Conclusão

Neste tutorial, você aprendeu sobre a importância das interfaces na engenharia de software e como implementá-las em Python. Você viu como criar interfaces informais, que definem métodos que podem ser sobrescritos, mas sem uma aplicação estrita. Além disso, você aprendeu como criar interfaces formais utilizando a biblioteca abc, que fornece suporte para a criação e implementação de interfaces com métodos abstratos.

Lembre-se de que o uso de interfaces pode ajudar a melhorar a estrutura e a organização do seu código, permitindo que você defina contratos claros entre as classes e promovendo um baixo acoplamento e alta coesão entre os componentes do seu sistema.

Continue praticando e explorando como as interfaces podem ser úteis em seus próprios projetos. Experimente criar suas próprias interfaces e implemente classes que as utilizam. Quanto mais você se familiarizar com o uso de interfaces em Python, mais poderá aproveitar as vantagens dessa abordagem em seus projetos futuros.

[ REMOVE ADS ]