public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
¿Cómo implemento 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!'
¿¿Es esta una buena idea?? Por favor, da ejemplos en tus respuestas.
raise NotImplementedError
es loshow
que debería ser el cuerpo, ¡no tiene sentido criar un genérico completamenteException
cuando Python define uno incorporado perfectamente específico! -)Respuestas:
Según lo mencionado por otro aquí:
Las interfaces no son necesarias en Python. Esto se debe a que Python tiene una herencia múltiple adecuada, y también ducktyping, lo que significa que los lugares donde debe tener interfaces en Java, no tiene que tenerlas en Python.
Dicho esto, todavía hay varios usos para las interfaces. Algunos de ellos están cubiertos por Pythons Abstract Base Classes, introducidos en Python 2.6. Son útiles si desea crear clases base que no se puedan instanciar, pero que proporcionen una interfaz específica o parte de una implementación.
Otro uso es si de alguna manera desea especificar que un objeto implementa una interfaz específica, y también puede usar ABC para eso subclasificando de ellos. Otra forma es zope.interface, un módulo que forma parte de Zope Component Architecture, un marco de componentes realmente genial. Aquí no se subclasifican las interfaces, sino que se marcan las clases (o incluso las instancias) como implementando una interfaz. Esto también se puede utilizar para buscar componentes desde un registro de componentes. ¡Super guay!
fuente
El uso del módulo abc para clases base abstractas parece ser el truco.
fuente
if not server.version() == '1.0': raise ...
? Realmente no entiendo esta línea. Una explicación sería bienvenida.La interfaz es compatible con Python 2.7 y Python 3.4+.
Para instalar la interfaz tienes que
Código de ejemplo:
fuente
Implementar interfaces con clases base abstractas es mucho más simple en Python 3 moderno y sirven como un contrato de interfaz para extensiones de plug-in.
Cree la interfaz / clase base abstracta:
Cree una subclase normal y anule todos los métodos abstractos:
Opcionalmente, puede tener una implementación común en los métodos abstractos como en
create_sale_invoice()
, llamándolosuper()
explícitamente en la subclase como anteriormente.La creación de instancias de una subclase que no implementa todos los métodos abstractos falla:
También puede tener propiedades abstractas, métodos estáticos y de clase combinando las anotaciones correspondientes con
@abstractmethod
.Las clases base abstractas son excelentes para implementar sistemas basados en complementos. Se puede acceder a todas las subclases importadas de una clase
__subclasses__()
, por lo que si carga todas las clases desde un directorio de complementosimportlib.import_module()
y si subclasan la clase base, tiene acceso directo a ellas a través de__subclasses__()
y puede estar seguro de que el contrato de interfaz se aplica para todos ellos durante la instanciación.Aquí está la implementación de carga de complementos para el
AccountingSystem
ejemplo anterior:Luego puede acceder al objeto de complemento del sistema de contabilidad a través de la
AccountingSystem
clase:(Inspirado en esta publicación de PyMOTW-3 ).
fuente
Hay implementaciones de interfaces de terceros para Python (la más popular es Zope , también utilizada en Twisted ), pero más comúnmente los codificadores de Python prefieren usar el concepto más rico conocido como "Clase base abstracta" (ABC), que combina una interfaz con la posibilidad de tener algunos aspectos de implementación allí también. ABC está particularmente bien soportado en Python 2.6 y versiones posteriores, vea el PEP , pero incluso en versiones anteriores de Python normalmente se los ve como "el camino a seguir" - solo defina una clase cuyos métodos generen
NotImplementedError
para que las subclases sean ¡Aviso que es mejor que anulen esos métodos! -)fuente
Algo como esto (podría no funcionar ya que no tengo Python):
fuente
__init__(self)
el constructor?abc.ABC
es mucho mejor que aumentarNotImplementedError
: la creación de instancias de unaabc.ABC
subclase que no implementa todos los métodos abstractos falla temprano, por lo que está protegido contra errores. Vea mi respuesta a continuación para ver cómo se ve el error.Tengo entendido que las interfaces no son tan necesarias en lenguajes dinámicos como Python. En Java (o C ++ con su clase base abstracta), las interfaces son medios para garantizar que, por ejemplo, esté pasando el parámetro correcto, capaz de realizar un conjunto de tareas.
Por ejemplo, si tiene observador y observable, observable está interesado en suscribir objetos que admitan la interfaz IObserver, que a su vez tiene
notify
acción. Esto se verifica en tiempo de compilación.En Python, no existe tal cosa
compile time
y las búsquedas de métodos se realizan en tiempo de ejecución. Además, uno puede anular la búsqueda con los métodos mágicos __getattr __ () o __getattribute __ (). En otras palabras, puede pasar, como observador, cualquier objeto que pueda devolver invocable al acceder alnotify
atributo.Esto me lleva a la conclusión de que las interfaces en Python existen : es solo que su aplicación se pospone hasta el momento en que se usan realmente
fuente