varias - Cómo heredar de una clase base abstracta escrita en C#
herencia y polimorfismo c# (2)
Estoy intentando heredar de una clase base .NET abstracta en Python (2.7) usando Python.NET (2.1.0). Soy un Python n00b pero por lo que entendí ...
Esto es lo que logré hacer solo en Python y que funciona bien:
import abc
class Door(object):
__metaclass__ = abc.ABCMeta
def open(self):
if not self.is_open():
self.toggle()
def close(self):
if self.is_open():
self.toggle()
@abc.abstractmethod
def is_open(self):
pass
@abc.abstractmethod
def toggle(self):
pass
class StringDoor(Door):
def __init__(self):
self.status = "closed"
def is_open(self):
return self.status == "open"
def toggle(self):
if self.status == "open":
self.status = "closed"
else:
self.status = "open"
class BooleanDoor(Door):
def __init__(self):
self.status = True
def is_open(self):
return self.status
def toggle(self):
self.status = not (self.status)
Door.register(StringDoor)
Door.register(BooleanDoor)
Ahora, todo lo que hice fue reemplazar la puerta de la clase base abstracta por una representación de C #:
namespace PythonAbstractBaseClass
{
public abstract class Door
{
public virtual void Open()
{
if (!IsOpen())
Toggle();
}
public virtual void Close()
{
if (IsOpen())
Toggle();
}
public abstract bool IsOpen();
public abstract void Toggle();
}
}
Al eliminar Door de la parte de Python e importarlo del ensamblado .NET, acabo con esto:
import clr
import abc
from PythonAbstractBaseClass import Door
class StringDoor(Door):
def __init__(self):
self.status = "closed"
def is_open(self):
return self.status == "open"
def toggle(self):
if self.status == "open":
self.status = "closed"
else:
self.status = "open"
class BooleanDoor(Door):
def __init__(self):
self.status = True
def is_open(self):
return self.status
def toggle(self):
self.status = not (self.status)
Door.register(StringDoor)
Door.register(BooleanDoor)
Pero esto falla con el siguiente mensaje de error:
Door.register(StringDoor)
AttributeError: type object ''Door'' has no attribute ''register''
Por lo que entendí acerca de abc.ABCMeta
, esta metaclase contribuye con el método register()
. Parece que las clases abstractas de C # no vienen con la misma metaclase. En su lugar, vienen con metaclass CLR Metatype
que, obviamente, no proporciona register()
.
Pero si abandono la llamada a register()
, al crear una instancia de una de las clases derivadas, recibo el mensaje de error
sdoor = StringDoor()
TypeError: cannot instantiate abstract class
¿Hay alguna forma de heredar de una clase .NET abstracta o es una característica que falta?
Gracias por adelantado,
Henning
No estoy familiarizado con pythonnet (o python en general), pero tengo curiosidad de que algo como esto pueda funcionar:
import clr
import abc
from PythonAbstractBaseClass import Door
class DoorWrapper(Door):
__metaclass__ = abc.ABCMeta
class StringDoor(DoorWrapper):
...
class BooleanDoor(DoorWrapper):
...
DoorWrapper.register(StringDoor)
DoorWrapper.register(BooleanDoor)
No puede crear una nueva instancia de una clase abstracta en C #. Dicho esto, Python requerirá que uses el registro, ya que no te permitirá usar tu clase heredada sin registrarlo, a menos que lo instales.
Si desea heredar de una clase abstracta de C # en python, tendrá que escribir por su cuenta la representación de la clase de registro en python en su clase de C #, por lo tanto, registrará su llamada abstracta y podrá heredar de ella.
Le sugeriría este sitio para que lo ayude a convertir fácilmente entre los códigos si es necesario: