Подтвердить что ты не робот

Как наследовать от абстрактного базового класса, написанного на С#

Im пытается наследовать от абстрактного базового класса .NET в Python (2.7) с использованием Python.NET(2.1.0). Im a Python n00b, но из того, что я понял...

Вот что мне удалось сделать только на Python и отлично работает:

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)

Теперь все, что я делал, это заменить абстрактный класс класса Door на представление С#:

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();
    }
}

Удалив дверь из части Python и импортируя ее из сборки .NET, я получаю следующее:

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)

Но это не соответствует следующему сообщению об ошибке:

    Door.register(StringDoor)
AttributeError: type object 'Door' has no attribute 'register'

Из того, что я понял о abc.ABCMeta, этот метакласс вносит свой вклад в метод register(). Кажется, что абстрактные классы С# не имеют одинакового метакласса. Вместо этого они появляются с метаклассом CLR Metatype, который, очевидно, не предоставляет register().

Но если я опускаю вызов register(), при создании экземпляра одного из производных классов я получаю сообщение об ошибке

    sdoor = StringDoor()
TypeError: cannot instantiate abstract class

Есть ли способ наследовать от абстрактного класса .NET или это недостающая функция?

Спасибо заранее,

Хеннинга

4b9b3361

Ответ 1

Вы не можете создать новый экземпляр абстрактного класса в С#. что Python потребует от вас использовать регистр, так как он не позволит вам использовать ваш унаследованный класс без его регистрации, если вы не создадите его.

если вы хотите наследовать от абстрактного класса С# в python, вам придется самостоятельно написать представление класса register в python в вашем классе С#, таким образом, зарегистрируйте свой абстрактный вызов и сможете наследовать его.

Я бы предложил этот сайт легко помочь вам конвертировать между кодами, если нужно:

https://www.varycode.com/converter.html

Ответ 2

Я вообще не знаком с pythonnet (или вообще python вообще), но мне любопытно, может ли что-то вроде этого работать:

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)