Python:我应该在这里使用委托还是继承?

时间:2012-05-22 14:49:55

标签: 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 """
        ...

......还有更多的行为。现在我的代码需要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"""
        ...

当然我也可以致电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())

在这种情况下,授权将是最佳选择。 (我不知道这是否可以使用继承来完成):

class Anaconda:

    def __init__(self, python):
        self.python = python

    def wriggle(self):
        self.python.wriggle()


    def devourCrocodile(self, croc):
        ...

但是有了代表团,我不能打电话给Anaconda().sleep()

所以,如果你还在我身边,我的问题是:

A)在类似的情况下,我需要

  • 添加一些功能
  • 重命名某些功能
  • 使用“基类”功能否则
  • 将“基类”对象转换为“子类”对象

我应该使用继承还是委托? (或其他什么?)

B)一个优雅的解决方案是使用委托加一些特殊方法,将Anaconda不响应的所有属性和方法访问转发到其Python的实例。

1 个答案:

答案 0 :(得分:7)

  

B)一个优雅的解决方案是使用委托加上一些特殊的方法来转发Anaconda不响应其Python实例的所有属性和方法访问。

这在Python中很简单,只需定义__getattr__

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)

请参阅__getattr__

上的Python文档