简体   繁体   English

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

[英]Python: Should I use delegation or inheritance here?

I am pondering if I should use inheritance or delegation to implement a kind of wrapper class. 我在思考是否应该使用继承或委托来实现一种包装类。 My problem is like this: Say I have a class named Python . 我的问题是这样的:假设我有一个名为Python的类。

class Python:

    def __init__(self):
        ...

    def snake(self):
        """ Make python snake through the forest"""
        ...

    def sleep(self):
        """ Let python sleep """
        ...

... and much more behavior. ......还有更多的行为。 Now I have existing code which expects an Anaconda , which is almost like a Python , but slightly different: Some members have slightly different names and parameters, other members add new functionality. 现在我有一些代码需要一个Anaconda ,它几乎就像一个Python ,但略有不同:一些成员的名称和参数略有不同,其他成员添加了新的功能。 I really want to reuse the code in Python . 我真的想在Python重用代码。 Therefore I could do this with inheritance: 因此我可以通过继承来做到这一点:

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"""
        ...

Of course I can also call Anaconda().sleep() . 当然我也可以打电话给Anaconda().sleep() But here is the problem: There is a PythonFactory which I need to use. 但问题是:我需要使用PythonFactory

class PythonFactory:

    def makeSpecialPython(self):
        """ Do a lot of complicated work to produce a special python"""
        …
        return python

I want it to make a Python and then I should be able to convert it to an Anaconda : 我想要它制作一个Python ,然后我应该能够将它转换为Anaconda

myAnaconda = Anaconda(PythonFactory().makeSpecialPython())

In this case, delegation would be the way to go. 在这种情况下,授权将是一条路。 (I don't know whether this can be done using inheritance): (我不知道是否可以使用继承来完成):

class Anaconda:

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

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


    def devourCrocodile(self, croc):
        ...

But with delegation, I cannot call Anaconda().sleep() . 但是有了代表团,我不能打电话给Anaconda().sleep()

So, if you're still with me, my questions are: 所以,如果你还在我身边,我的问题是:

A) In a case similar to this, where I need to A)在类似的情况下,我需要

  • add some functionality 添加一些功能
  • rename some functionality 重命名一些功能
  • use "base class" functionality otherwise 否则使用“基类”功能
  • convert "base class" object to "subclass" object 将“基类”对象转换为“子类”对象

should I use inheritance or delegation? 我应该使用继承还是委托? (Or something else?) (或者是其他东西?)

B) An elegant solution would be to use delegation plus some special method that forwards all attribute and method accesses which Anaconda does not respond to to its instance of Python . B)一个优雅的解决方案是使用委托加上一些特殊的方法来转发Anaconda不响应其Python实例的所有属性和方法访问。

B) An elegant solution would be to use delegation plus some special method that forwards all attribute and method accesses which Anaconda does not respond to to its instance of Python. B)一个优雅的解决方案是使用委托加上一些特殊的方法来转发Anaconda不响应其Python实例的所有属性和方法访问。

This is simple in Python, just define __getattr__ : 这在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)

See the Python docs on __getattr__ 请参阅__getattr__上的Python文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM