多重继承依赖 - Base 需要 AbstractBaseClass



问题的要点:如果继承多个类,我如何保证如果继承了一个类,子对象也使用补充抽象基类(abc(。

我一直在搞乱 python 的继承,试图看看我能做什么样的很酷的事情,我想出了这个模式,这很有趣。

我一直在尝试使用它来更轻松地实现和测试与缓存交互的对象。 我有三个模块:

  • ICachable.py
  • Cacheable.py
  • SomeClass.py

ICacheable.py

import abc
class ICacheable(abc.ABC):
@property 
@abc.abstractmethod
def CacheItemIns(self):
return self.__CacheItemIns
@CacheItemIns.setter
@abc.abstractmethod
def CacheItemIns(self, value):
self.__CacheItemIns = value
return

@abc.abstractmethod
def Load(self):
"""docstring"""
return
@abc.abstractmethod
def _deserializeCacheItem(self): 
"""docstring"""
return
@abc.abstractmethod
def _deserializeNonCacheItem(self): 
"""docstring"""
return

Cacheable.py

class Cacheable:

def _getFromCache(self, itemName, cacheType,
cachePath=None):
"""docstring"""

kwargs = {"itemName" : itemName, 
"cacheType" : cacheType,
"cachePath" : cachePath}

lstSearchResult = CacheManager.SearchCache(**kwargs)
if lstSearchResult[0]:
self.CacheItemIns = lstSearchResult[1]
self._deserializeCacheItem()
else:
cacheItem = CacheManager.NewItem(**kwargs)
self.CacheItemIns = cacheItem
self._deserializeNonCacheItem()

return

SomeClass.py

import ICacheable
import Cacheable
class SomeClass(Cacheable, ICacheable):
__valueFromCache1:str = ""
__valueFromCache2:str = ""
__CacheItemIns:dict = {}
@property 
def CacheItemIns(self):
return self.__CacheItemIns
@CacheItemIns.setter
def CacheItemIns(self, value):
self.__CacheItemIns = value
return
def __init__(self, itemName, cacheType):
#Call Method from Cacheable
self.__valueFromCache1
self.__valueFromCache2
self.__getItemFromCache(itemName, cacheType)
return
def _deserializeCacheItem(self): 
"""docstring"""
self.__valueFromCache1 = self.CacheItemIns["val1"]
self.__valueFromCache2 = self.CacheItemIns["val2"]
return
def _deserializeNonCacheItem(self): 
"""docstring"""
self.__valueFromCache1 = #some external function
self.__valueFromCache2 = #some external function
return

所以这个例子有效,但可怕的是,无法保证一个类固有Cacheable也继承ICacheable。 这似乎是一个设计缺陷,因为Cacheable本身是无用的。 但是,使用它从我的子类/子类中抽象事物的能力非常强大。 有没有办法保证Cacheable对ICacheable的依赖性?

如果您明确不希望继承,则可以将类注册为 ABC 的虚拟子类。

@ICacheable.register
class Cacheable:
...

这意味着Cacheable的每个子类也自动被视为ICacheable的子类。如果您有一个高效的实现,并且可以通过遍历非功能性抽象基类来减慢速度,例如用于super调用,这将非常有用。

但是,ABC 不仅仅是接口,从它们继承是可以的。事实上,ABC 的部分好处是它强制子类来实现所有抽象方法。中间帮助程序类(如Cacheable(可以在从未实例化时不实现所有方法。但是,任何实例化的非虚拟子类都必须是具体的。

>>> class FailClass(Cacheable, ICacheable):
...    ...
...
>>> FailClass()
TypeError: Can't instantiate abstract class FailClass with abstract methods CacheItemIns, Load, _deserializeCacheItem, _deserializeNonCacheItem

请注意,如果您

  • 始终将子类作为class AnyClass(Cacheable, ICacheable):
  • 从不实例化Cacheable

这在功能上等同于从ICacheable继承Cacheable。方法解析顺序(即继承菱形(是相同的。

>>> AnyClass.__mro__
(__main__. AnyClass, __main__.Cacheable, __main__.ICacheable, abc.ABC, object)

最新更新