Python:我应该在这里使用委托还是继承?
我正在考虑是否应该使用继承或委托来实现一种包装类。我的问题是这样的:假设我有一个名为Python:我应该在这里使用委托还是继承?,python,oop,inheritance,python-3.x,delegation,Python,Oop,Inheritance,Python 3.x,Delegation,我正在考虑是否应该使用继承或委托来实现一种包装类。我的问题是这样的:假设我有一个名为Python的类 class Python: def __init__(self): ... def snake(self): """ Make python snake through the forest""" ... def sleep(self): """ Let python sleep """
Python
的类
class Python:
def __init__(self):
...
def snake(self):
""" Make python snake through the forest"""
...
def sleep(self):
""" Let python sleep """
...
。。。还有更多的行为。现在我有了一个现有的代码,它需要一个Anaconda
,这几乎像是一个Python
,但略有不同:一些成员的名称和参数略有不同,其他成员添加了新的功能。我真的很想重用Python
中的代码。因此,我可以通过继承做到这一点:
class Anaconda(Python):
def __init__(self):
Python.__init__(self)
def wriggle(self):
"""Different name, same thing"""
Python.snake(self)
def devourCrocodile(self, croc):
""" Python can't do this"""
...
class Anaconda:
def __init__(self, python):
self.python = python
def wriggle(self):
self.python.wriggle()
def devourCrocodile(self, croc):
...
当然,我也可以调用Anaconda().sleep()
。但问题是:我需要使用一个PythonFactory
class PythonFactory:
def makeSpecialPython(self):
""" Do a lot of complicated work to produce a special python"""
…
return python
我想让它成为一个Python
,然后我应该能够将它转换成Anaconda
:
myAnaconda = Anaconda(PythonFactory().makeSpecialPython())
在这种情况下,授权将是一条出路。(我不知道这是否可以通过继承来实现):
但由于授权,我不能调用Anaconda().sleep()
所以,如果你还和我在一起,我的问题是:
A) 在类似的情况下,我需要
- 添加一些功能
- 重命名某些功能
- 否则请使用“基类”功能
- 将“基类”对象转换为“子类”对象
Anaconda
对其Python
实例没有响应
B) 一个优雅的解决方案是使用委托加上一些特殊的方法来转发Anaconda对其Python实例不响应的所有属性和方法访问
这在Python中很简单,只需定义\uu getattr\uu
:
class Anaconda:
def __init__(self, python):
self.python = python
def wriggle(self):
self.python.snake()
def devourCrocodile(self, croc):
...
def __getattr__(self, name):
return getattr(self.python, name)
查看上的Python文档,我不明白为什么没有公共基类。我只是没有一个。我正在写“Anaconda”,“Python”和“PythonFactory”是我无法修改的现有代码。我介于现有代码集之间,需要对其中一个进行“调整”。谁将使用您的snake对象?他期望从对象中得到什么接口?接口之间的关系如何?“Anaconda”应该提供的接口由我正在重新实现的现有代码库决定(试图保持代码的相似性)。Anaconda是否也应该
snake()
或者只wriggle()
并拒绝snake())
好像它没有实现?旁注:适配器设计模式似乎是解决问题的理想方案。它与授权有关,但更具体。mensi的答案是适配器的Python实现。。。尽管该形式的wriggle()
的显式声明是不必要的(除非其主体调用self.python.snake()
)+1:)@Walter问题的来源就是这样的,所以假设有一点疏忽,我就纠正了它。剩下的问题是,Anaconda
是否也可以直接snake()
,否则def snake(self):可能需要提升NotImplementedError()
(或者返回NotImplemented
?尽管这可能会导致对Python.snake
进行评估…)