Python 具有不同接口的派生类

Python 具有不同接口的派生类,python,inheritance,adapter,Python,Inheritance,Adapter,以下代码: class Cache: def __init__(self): self._cache = [] def store(self, data): self._cache.append(data) def stats(self): print('We are caching {} elements'.format(len(self._cache))) class LegoCache(Cache):

以下代码:

class Cache:

    def __init__(self):
        self._cache = []

    def store(self, data):
        self._cache.append(data)

    def stats(self):
        print('We are caching {} elements'.format(len(self._cache)))


class LegoCache(Cache):

    def store(self, weight, color):
        Cache.store(self, (weight, color))
存在一个问题,
store
方法没有实现基类的接口

如何改进此代码?我有以下想法:

  • 不要从
    缓存中派生,只要利用它
  • 将基类中的
    store
    方法重命名为
    store\u base
还有其他选择吗

编辑 基类还必须支持此其他用例:

class ZombieCache(Cache):

    def store(self, dead_since, humans_eaten, can_be_saved=False):
        Cache.store(self, dict(
            dead_since=dead_since, 
            humans_eaten=humans_eaten, 
            can_be_saved=can_be_saved))

可以在基类中使用变量参数列表:

class Cache:

    def __init__(self):
        self._cache = []

    def store(self, *args):
        self._cache.append(args)

    def stats(self):
        print('We are caching {} elements'.format(len(self._cache)))

class LegoCache(Cache):
    pass
    # "overloading" store isn't needed
因此,不需要重载此方法或为特殊情况添加具有不同名称的方法:

cache = Cache()
legoCache = LegoCache()

cache.store(x)
legoCache.store(x, y)
另一种解决办法可能是授权:

class LegoCache(object):
    def __init__(self):
        self.cache = Cache()

    def store(self, weight, color):
        self.cache.store((weight, color))
        # or just self.cache.store(weight, color) if you use the *args implementation

我会这样实施,

class Cache:

  def __init__(self):
      self._cache = []

  def store(self, data):
      self._cache.append(data)

  def stats(self): 
      print('We are caching {} elements'.format(len(self._cache)))


class LegoData(object):

  def __init__(self, weight, color):
      self.weight = weight
      self.color = color

class LegoCache(Cache):
   pass
lego_cache = LegoCache()
lego_cache.store(LegoData(weight=10, color='Green'))
客户端将像这样访问它

class Cache:

  def __init__(self):
      self._cache = []

  def store(self, data):
      self._cache.append(data)

  def stats(self): 
      print('We are caching {} elements'.format(len(self._cache)))


class LegoData(object):

  def __init__(self, weight, color):
      self.weight = weight
      self.color = color

class LegoCache(Cache):
   pass
lego_cache = LegoCache()
lego_cache.store(LegoData(weight=10, color='Green'))

这真的重要吗?@stephernauch,
PyCharm
不快乐,所以我不快乐。但说真的,这不是一种代码味道吗?我是一个大派克,但这里的范围是什么?除了要求调用方存储以显式传递元组外:
store((weight,color))
,或者将基存储更改为
store(*args)
,那么args始终是元组。@Stephenauch,这些都不吸引我,因为派生类的全部目的是为调用方提供一个简化的接口,为了使一个接口适应另一个接口。很公平……Nononono,基类有一个定义良好的实现:它接受一个数据参数,它可以是任何东西。派生类为特定情况提供了一个更方便的接口。@dangonfast:事实上,这并不好。(Un-)幸运的是,Python不支持方法重载。如果您不喜欢这样,则必须为每个项类型声明特殊方法。但是请注意,您也可以在
LegoCache
中调用
store()
。但是你应该考虑使用委托而不是继承。@ DangOnFAST:我增加了一个委派例子。谢谢!对我来说,这似乎是最干净的解决办法。不幸的是,这个实现隐藏了一个事实,即这是从
缓存派生出来的,但是正如您所提到的,如果没有方法重载,就不可能实现这一点。
LegoCache
的全部要点是提供一个简单、可用的界面,以便用户可以轻松地使用它。此实现只提供一个基本的
缓存
,用户完全负责实例化数据。因此,
LegoCache
是多余的。另一方面,
LegoData
确实可以用作缓存的数据元素,但这是一个(ortogonal)实现细节,而不是我的问题。