I’m trying to inherit from an abstract .NET base class in Python (2.7) using Python.NET (2.1.0). I’m a Python n00b but from what I understood…
Here’s what I managed to do in Python only and which works fine:
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)
Now, all I did was to replace the abstract base class Door by a C# representation:
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();
}
}
Removing Door from the Python part and importing it from the .NET assembly instead, I end up with this:
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)
But this fails with the following error message:
Door.register(StringDoor)
AttributeError: type object 'Door' has no attribute 'register'
From what I understood about abc.ABCMeta
, this metaclass contributes the register()
method. It seems that abstract C# classes do not come with the same metaclass. They instead come with metaclass CLR Metatype
which obviously does not provide register()
.
But if I drop the call to register()
, on instantiating one of the derived classes, I receive the error message
sdoor = StringDoor()
TypeError: cannot instantiate abstract class
Is there a way to inherit from an abstract .NET class or is this a missing feature?
Thanks in advance,
Henning
NO. Abstract methods(defintion) are overridden by base class' overriding methods.
Abstract Class If a class is declared abstract, it cannot be instantiated. To use an abstract class, you have to inherit it from another class, provide implementations to the abstract methods in it. If you inherit an abstract class, you have to provide implementations to all the abstract methods in it.
As we all know that an interface can inherit another interface, and interface can only contain method signature. Now the class which implement interface B need to provide body of two functions. So why can't be a interface can inherit a abstract class or a normal class.
Abstract classes in C++ need to have at least one pure virtual function in a class. The classes that inherit the abstract class must provide a definition for the pure virtual function, else the subclass will itself become an abstract class.
You cannot create a new instance of an abstract class in C#. that said, Python will require you to use the register, as it will not allow you to use your inherited class without registering it, unless you instantiate it.
if you want to inherit from an C# abstract class in python, you will have to write on your own the representation of register class in python at your C# class, thus will register your abstract call and be able to inherit from it.
I would suggest this site to easily help you convert between the codes if need to:
https://www.varycode.com/converter.html
I'm totally not familiar with pythonnet (or python in general for that matter), but I'm curious if something like this might work:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With