首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多继承依赖项-基本要求AbstractBaseClass

多继承依赖项-基本要求AbstractBaseClass
EN

Stack Overflow用户
提问于 2018-08-09 00:46:48
回答 1查看 122关注 0票数 0

问题的要点是:如果继承多个类,那么如果继承了一个类,那么子对象也会使用一个互补抽象基类(abc)。

我一直在处理蟒蛇的遗传问题,想看看我能做什么很酷的事情,我想出了这个模式,这是很有趣的。

我一直试图使用它来实现和测试与缓存接口的对象。我有三个模块:

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

ICacheable.py

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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本身是无用的。但是,用它从子类/子类中抽象事物的能力非常强大。是否有一种方法可以保证缓存对ICacheable的依赖?

EN

回答 1

Stack Overflow用户

发布于 2018-08-09 16:10:14

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

代码语言:javascript
复制
@ICacheable.register
class Cacheable:
    ...

这意味着Cacheable的每个子类也自动被视为ICacheable的子类。如果您有一个高效的实现,并且需要遍历非功能抽象基类(例如,对于super调用),那么这是非常有用的。

然而,ABC不仅仅是接口,从它们继承也是很好的。事实上,ABC的部分好处在于它强制子类实现所有抽象方法。中间助手类(如Cacheable )可以在从未实例化的情况下不实现所有方法。但是,任何被实例化的非虚拟子类都必须是具体的.

代码语言:javascript
复制
>>> class FailClass(Cacheable, ICacheable):
...    ...
...
>>> FailClass()
TypeError: Can't instantiate abstract class FailClass with abstract methods CacheItemIns, Load, _deserializeCacheItem, _deserializeNonCacheItem

注意如果你

  • 始终子类为class AnyClass(Cacheable, ICacheable):
  • 永远不要实例化Cacheable

这在功能上相当于CacheableICacheable继承。方法解析顺序(即继承钻石)是相同的。

代码语言:javascript
复制
>>> AnyClass.__mro__
(__main__. AnyClass, __main__.Cacheable, __main__.ICacheable, abc.ABC, object)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51757408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档