Python: Should I use delegation or inheritance here?

I am considering whether to use inheritance or delegation to implement some kind of wrapper class. My problem is this: Let's say I have a class called Python .

 class Python: def __init__(self): ... def snake(self): """ Make python snake through the forest""" ... def sleep(self): """ Let python sleep """ ... 

... and much more. Now I have some code that Anaconda expects, which is almost like Python , but slightly different: some members have slightly different names and parameters, others add new functions. I really want to reuse code in 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() . But here is the problem: there is a PythonFactory that I need to use.

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

I want him to make Python , and then I would have to convert it to Anaconda :

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

In this case, the delegation will be the path. (I don't know if 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 a delegation, I cannot call Anaconda().sleep() .

So, if you are still with me, my questions are:

A) In a case similar to this, where I need

  • add some features
  • rename some functions
  • use the functionality of the "base class" otherwise
  • convert a base class object to a subclass object

Should I use inheritance or delegation? (Or something else?)

B) An elegant solution would be to use delegation plus a special method that forwards all calls to attributes and methods that Anaconda does not respond to its Python instance.

+4
source share
1 answer

B) An elegant solution would be to use delegation plus some special method that forwards all calls to attributes and methods that Anaconda does not respond to its Python instance.

It is simple in Python, just define __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 Python __getattr__ at __getattr__

+7
source

Source: https://habr.com/ru/post/1413775/


All Articles