public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
Como eu implemento o Python equivalente a este código C #?
class IInterface(object):
def __init__(self):
pass
def show(self):
raise Exception("NotImplementedException")
class MyClass(IInterface):
def __init__(self):
IInterface.__init__(self)
def show(self):
print 'Hello World!'
Isso é uma boa ideia?? Por favor, dê exemplos em suas respostas.
raise NotImplementedError
é o queshow
o corpo deveria ser - não faz sentido criar uma abordagem completamente genéricaException
quando o Python define um embutido perfeitamente específico!)Respostas:
Como mencionado por outro aqui:
As interfaces não são necessárias no Python. Isso ocorre porque o Python possui herança múltipla adequada e também tipagem de patinhos, o que significa que nos locais em que você deve ter interfaces em Java, não é necessário tê-las em Python.
Dito isto, ainda existem vários usos para interfaces. Alguns deles são abordados pelas Pythons Abstract Base Classes, introduzidas no Python 2.6. Eles são úteis, se você deseja criar classes base que não podem ser instanciadas, mas fornecem uma interface específica ou parte de uma implementação.
Outro uso é se você, de alguma forma, deseja especificar que um objeto implementa uma interface específica e também pode usar ABCs para isso, subclassificando-os. Outra maneira é o zope.interface, um módulo que faz parte da Arquitetura de Componentes do Zope, uma estrutura de componentes realmente incrível. Aqui você não faz subclasse das interfaces, mas marca classes (ou mesmo instâncias) como implementando uma interface. Isso também pode ser usado para procurar componentes de um registro de componente. Muito legal!
fonte
Usar o módulo abc para classes base abstratas parece fazer o truque.
fonte
if not server.version() == '1.0': raise ...
:? Eu realmente não entendo essa linha. Uma explicação seria bem-vinda.A interface suporta Python 2.7 e Python 3.4+.
Para instalar a interface, você precisa
Código de exemplo:
fonte
A implementação de interfaces com classes base abstratas é muito mais simples no Python 3 moderno e serve a um propósito como contrato de interface para extensões de plug-in.
Crie a interface / classe base abstrata:
Crie uma subclasse normal e substitua todos os métodos abstratos:
Opcionalmente, você pode ter uma implementação comum nos métodos abstratos como em
create_sale_invoice()
, chamando-asuper()
explicitamente na subclasse como acima.Falha na instanciação de uma subclasse que não implementa todos os métodos abstratos:
Você também pode ter propriedades abstratas, métodos estáticos e de classe combinando anotações correspondentes com
@abstractmethod
.As classes base abstratas são ótimas para implementar sistemas baseados em plugins. Todas as subclasses importadas de uma classe são acessíveis via
__subclasses__()
, portanto, se você carregar todas as classes de um diretório de plug-insimportlib.import_module()
e se elas subclassificarem a classe base, você terá acesso direto a elas via__subclasses__()
e poderá ter certeza de que o contrato de interface é aplicado a todos eles durante a instanciação.Aqui está a implementação de carregamento do plug-in para o
AccountingSystem
exemplo acima:Em seguida, você pode acessar o objeto de plug-in do sistema de contabilidade por meio da
AccountingSystem
classe:(Inspirado por este post do PyMOTW-3 .)
fonte
Existem implementações de interfaces de terceiros para Python (o mais popular é o Zope , também usado no Twisted ), mas mais comumente os codificadores Python preferem usar o conceito mais rico conhecido como "Abstract Base Class" (ABC), que combina uma interface com a possibilidade de ter alguns aspectos de implementação lá também. Os ABCs são particularmente bem suportados no Python 2.6 e versões posteriores, veja o PEP , mas mesmo nas versões anteriores do Python elas são normalmente vistas como "o caminho a percorrer" - basta definir uma classe que alguns de cujos métodos aumentam
NotImplementedError
para que as subclasses sejam no aviso de que é melhor substituir esses métodos! -)fonte
Algo assim (pode não funcionar, pois não tenho Python por perto):
fonte
__init__(self)
o construtor?abc.ABC
é muito melhor do que aumentarNotImplementedError
- a instanciação de umaabc.ABC
subclasse que não implementa todos os métodos abstratos falha mais cedo, portanto, você está protegido contra erros. Veja minha resposta abaixo para saber como é o erro.Meu entendimento é que as interfaces não são tão necessárias em linguagens dinâmicas como Python. Em Java (ou C ++ com sua classe base abstrata), as interfaces são meios para garantir que, por exemplo, você esteja passando o parâmetro certo, capaz de executar um conjunto de tarefas.
Por exemplo, se você tem um observador e um observável, o observável está interessado em assinar objetos que suportem a interface IObserver, que por sua vez
notify
ação. Isso é verificado no momento da compilação.No Python, não existe,
compile time
e as pesquisas de método são executadas em tempo de execução. Além disso, pode-se substituir a pesquisa pelos métodos mágicos __getattr __ () ou __getattribute __ (). Em outras palavras, você pode passar, como observador, qualquer objeto que possa retornar para chamar ao acessar onotify
atributo.Isso me leva à conclusão de que as interfaces no Python existem - é apenas que sua aplicação é adiada para o momento em que são realmente usadas
fonte