Я стремлюсь разделить проблемы, используя многоуровневую архитектуру в моем дизайне. Чтобы добиться этого, я определяю основные свойства объекта, используя Абстрактные базовые классы (AB C), например ::
from abc import ABC, abstractmethod
class AbstractPerson(ABC):
@property
@abstractmethod
def name(self):
pass
, которые затем я использую на прикладном уровне:
class Person(AbstractPerson):
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
Уровень персистентности должен быть отделен от приложения, поэтому я определяю Pony-классы:
from pony import orm
def define_pony_person(database):
class PonyPerson(database.Entity, AbstractPerson):
name = orm.Required(
str,
unique=True
)
return PonyPerson
Наследование от AbstractPerson предназначено для принудительного выполнения контракта Person через слои. Чем в коде клиента (например, бизнес-логи c) я мог бы создать экземпляр и использовать свой основной объект:
person = Person(
name='Foo'
)
, а в какой-то другой части кода (например, в репозитории) я бы сохранил его:
db = orm.Database()
PonyPerson = define_pony_person(db)
db.bind('sqlite', ':memory:')
db.generate_mapping(create_tables=True)
pony_person = PonyPerson(
name=person.name
)
Но когда я пытаюсь сделать это таким образом, оказывается, что Пони-сущность не смешивается с AB C плавно:
Traceback (most recent call last):
File "./test.py", line 43, in <module>
define_pony_person(db)
File "./test.py", line 28, in define_pony_person
class PonyPerson(database.Entity, AbstractPerson):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Есть ли способ принудительного исполнения моего контракта с основным объектом на объекте Pony в соответствии с набросками, описанными выше?