If some class extends abc class (Abstract Base Class) then I can't instantiate it unless I define all abstract methods. But often when implementing Decorator pattern, I want to define only a few abstract methods, and others - just delegate to decorated object. How to do this?
For example, I want to make the following code work:
from abc import ABCMeta, abstractmethod
class IElement(object):
__metaclass__ = ABCMeta
@abstractmethod
def click(self):
return
@abstractmethod
def hover(self):
return
# ... more IElement's abstractmethods...
class StandardElement(IElement):
def click(self):
return "click"
def hover(self):
return "hover"
# ... more implemented IElement's methods...
class MyElement(IElement):
def __init__(self, standard_element):
self._standard_element = standard_element
delegate(IElement, standard_element)
def click(self):
return "my click"
assert MyElement(StandardElement()).click() == 'my click'
assert MyElement(StandardElement()).hover() == 'click'
instead of
from abc import ABCMeta, abstractmethod
class IElement(object):
__metaclass__ = ABCMeta
@abstractmethod
def click(self):
return
@abstractmethod
def hover(self):
return
# ... more IElement's abstractmethods...
class StandardElement(IElement):
def click(self):
return "click"
def hover(self):
return "hover"
# ... more implemented IElement's methods...
class MyElement(IElement):
def __init__(self, standard_element):
self._standard_element = standard_element
def click(self):
return "my click"
def hover(self):
return self._standard_element.hover()
# ... more manually delegated IElement's methods to self._standard_element object, aggregated in initialiser...
assert MyElement(StandardElement()).click() == 'my click'
assert MyElement(StandardElement()).hover() == 'click'
For this I need to implement the delegate
method from example above. How to implement it? Some other approaches to provide automatic delegation for classes extending abc classes may also be considered.
P.S.
Please do not propose me Inheritance (class MyElement(StandardElement)
) as a solution here... The code provided above is just an example. In my real case MyElement is pretty different thing comparing to StandardElement. Still, I have to make MyElement compatible with StandardElement, because sometimes someone is supposed to use MyElement instead of StandardElement. I really need to implement "has a" relationship here, not "is a".