多重继承依赖基需要AbstractBaseClass

2024-10-03 23:28:48 发布

您现在位置:Python中文网/ 问答频道 /正文

问题的要点:如果继承多个类,我如何保证如果继承了一个类,子对象也会使用一个补充抽象基类(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

你知道吗可缓存.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

你知道吗某某班级.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的依赖性?你知道吗


Tags: pyselfreturnvaluedefdocstringabcabstractmethod
1条回答
网友
1楼 · 发布于 2024-10-03 23:28:48

如果显式不希望继承,可以将类注册为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)

相关问题 更多 >