I'm just curious why all examples of proxy-pattern written in Python are using composition over inheritance? If proxy class should implement all of the methods of original class, isn't it easier to inherit proxy from original and just overwrite methods we want to perform additional logic (caching, logging, etc.), using super().method()?
The relationship between classes is also respected: the proxy class is some kind of an original class.
Example:
class Original:
def some_method(self):
return "some"
def another_method(self):
return "another"
class Proxy(Original):
def another_method(self):
res = super().another_method()
logger.log(res)
return res
Lets take a look at one of the "classical" diagrams for proxy pattern (from wiki):
I would argue that "If proxy class should implement all of the methods of original class" statement is not true - the proxy class should implement all of the "contract" methods (
Subjectinterface) and it hides the implementation detail i.e.RealSubjectfrom the user (alsoRealSubjectpotentially can have some other public methods not defined by the interface).One more thing to consider - composition can give the proxy ability to control the lifetime of the proxied class instance, while with inheritance (if we skip the fact that there is no more "proxying" happening) it is not possible for the "proxy" itself.
Also note that there are benefits (and drawbacks) in choosing composition over inheritance in general.
Some more useful reading: