Im试图实现Mixin模式,同时使用PydanticsBaseClass
来促进类中数据的实例化和验证。问题是我的Mixin无法从基类中抑制(实际上,依赖关系正好相反(。此外,我使用mypy,所以我的实现需要正确地键入。
让我们看一个简化的例子:
class BaseCart(BaseModel):
id: int
items: List[Item]
adress: str
class CartInterface(ABC):
@abstractproperty
def id(self):
...
@abstractproperty
def items(self):
...
@abstractproperty
def adress(self):
...
@abstractmethod
def get_shipping_value(self):
...
@abstractmethod
def get_items_availability(self):
...
class ShippingMixin(ABC, CartInterface):
def get_shipping_value(self) -> int:
# some business logic using self.address to calculate
class NormalItemsMixin(ABC, CartInterface):
def get_items_availability(self) -> bool:
# iterate over self.items and check stock availability
class AwesomeItemsMixin(ABC, CartInterface):
def get_items_availability(self) -> bool:
# iterate over self.items and check stock availability
# this implementation is different from the normal one
class NormalCart(BaseCart, ShippingMixin, NormalItemsMixin):
...
class AwesomeCart(BaseCart, ShippingMixin, AwesomeItemsMixin):
...
问题是,实现后,我无法实例化AwesomeCart
,我得到以下错误:TypeError: Can't instantiate abstract class ResellerCart with abstract methods business_unit, cart_type, channel, id, items, reseller, status, updated_at
我错过了什么?
TLDR:为什么这个
class Data(BaseModel):
a: int
class IData(ABC):
@abstractproperty
def a(self):
...
class XData(Data, IData):
...
当我启动XData
时会引发TypeError: Can't instantiate abstract class XData with abstract method a
,喜欢x = XData(a=1)
吗?
在IData中,a
仅为"masquarading";作为一个属性,而实际上它是类的一个方法。你必须做一些类似的事情
class Data(BaseModel):
_a: int
@property
def a(self):
return self._a
class IData(ABC):
@abstractproperty
def a(self):
pass
class XData(Data, IData):
pass
现在Data
中的a
也是一个方法,代码按预期工作。
@abstractproperty
自python 3.3以来已弃用,请将"property"与"abstractmethod"一起使用。
class IData(ABC):
@property
@abstractmethod
def a(self):
pass