Introduction
Delegation is like passing a job to someone else. In Python, you can do this by using a method called __getattr()__. It’s almost like asking one object to do a task for another object, just like a subclass asking its parent class for help. Here you can find an article explaining this in more detail.
Implementation in Python
Let’s say we want to create a windowing system. We have a basic window that can open and close. We want to add more features to it, like rotating the window.
To make this happen, we create a WindowsDelegator class, which helps other classes delegate their work. In our case, we’ll use it with the BasicWindow class:
class WindowsDelegator:
    _delegate: object = None
    def __init__(self):
        self._delegate = self.get_delegate()
    def get_delegate(self) -> object:
        raise NotImplementedError
    def __getattr__(self, name):
        return getattr(self._delegate, name)Here’s what’s happening:
- We need something to delegate to, called _delegate.
- In the constructor, we call the get_delegate()method to set this attribute.
- The get_delegate()method is not fully implemented here because it needs to be defined in subclasses.
- We define the __getattr()method, which tries to find an attribute in the_delegateobject. If it can’t find it, it raises an exception.
Now let’s look at the BasicWindow class:
class BasicWindow(WindowsDelegator):
    _title: str = None
    def __init__(self, title: str):
        super().__init__()
        self._title = title
    def open(self):
        print(f"Opening window with title: {self._title}")
    def close(self):
        print(f"Closing window with title: {self._title}")
    @property
    def title(self) -> str:
        return self._title
    def get_delegate(self) -> object:
        return ExtendedWindow(self)
Here’s what’s happening:
- BasicWindowuses the- WindowsDelegator.
- It has a title, open, and close methods.
- The get_delegate()method returns an instance of theExtendedWindowclass.
Finally we can implement the ExtendedWindow class:
class ExtendedWindow:
    _window: BasicWindow = None
    def __init__(self, window: BasicWindow):
        self._window = window
    def rotate(self, degrees: int):
        print(f"Rotating window with title {self._window.title} by {degrees} degrees")
A summary:
- We embed a BasicWindowin this class to be able to access its properties, which we will need as you shall see.
- In the constructor we set the appropiate values
- In the rotate()method access the title of theBasicWindowtitle property to print out a message.
Testing time
The proof is in the pudding, so let’s test it:
if __name__ == "__main__":
    w = BasicWindow("My window")
    w.open()
    w.rotate(45)
    w.close()A summary:
- Create a BasicWindow
- We open, rotate and close this window. Notice that the call to rotate()automatically redirects to the functionality inExtendedWindow
Conclusion
In conclusion, while delegation is possible in Python, it may not always be the most Pythonic way to achieve your goals. It relies on low-level details and can become complex and less readable. If you can find a simpler way to do the same task, that might be a better choice.

 
                 
                