[Python.NET] Inheriting from abstract .NET class

Denis Akhiyarov denis.akhiyarov at gmail.com
Thu Sep 22 13:37:59 EDT 2016


You are not a "Python n00b" based on metaclass usage!

My recommendation is to keep simple integration layer between CPython and
.NET, hence metaclasses were/are not supported.

But contributions are welcome! Although I expect this to be a tremendous
undertaking based on reviewing multiple sources.

Note that metaclass is a very different low-level concept from higher-level
abstract classes in .NET, hence direct mapping (e.g. `.register()` ) is not
feasible.

Thanks,
Denis

On Thu, Sep 22, 2016 at 10:04 AM, Henning Moeller <HMoeller at comprion.com>
wrote:

> Hello out there,
>
>
>
> I’m trying to inherit from an abstract .NET base class in Python (2.7).
> I’m a Python n00b but from what I understood…
>
>
>
> Here’s what I managed to do in Python only and which works fine:
>
>
>
> [File: room.py] -------
>
> import abc
>
>
>
> class Room(object):
>
>     def __init__(self, door):
>
>         self.door = door
>
>
>
>     def open(self):
>
>         self.door.open()
>
>
>
>     def close(self):
>
>         self.door.close()
>
>
>
>     def is_open(self):
>
>         return self.door.is_open()
>
>
>
> 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:
>
>
>
> [File: PythonAbstractBaseClass.dll] -------
>
> 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:
>
>
>
> [File: room2.py] -------
>
> import clr
>
> import abc
>
> from PythonAbstractBaseClass import Door
>
>
>
> class Room(object):
>
>     def __init__(self, door):
>
>         self.door = door
>
>
>
>     def open(self):
>
>         self.door.open()
>
>
>
>     def close(self):
>
>         self.door.close()
>
>
>
>     def is_open(self):
>
>         return self.door.is_open()
>
>
>
> 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 is
> missing feature?
>
>
>
> Thanks in advance,
>
>
>
> Henning
>
>
>
> _________________________________________________
> Python.NET mailing list - PythonDotNet at python.org
> https://mail.python.org/mailman/listinfo/pythondotnet
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pythondotnet/attachments/20160922/09b1c1c0/attachment-0001.html>


More information about the PythonDotNet mailing list