List Of All Python Dunder Methods - Which Ones Do You Need To Implement To Correctly Proxy An Object?
Solution 1:
To proxy an object, you only need to implement the dunder methods that the object has, so in the simplest world, you wouldn't need to do anything special to proxy them that you're not already doing to proxy the object's other attributes.
However, the wrinkle is that dunder methods are looked up on the class, not on the object, so while for example Foo().bar
will look up bar
on the instance before falling back to the class if the instance has no bar
attribute, Foo() + 5
will look up __add__
on the class Foo
, completely ignoring the instance. That is, if the instance does have an instance attribute named __add__
, then Foo() + 5
still won't use that instance attribute.
So to proxy those dunder methods, they need to be proxied at the class level, not the instance level.
from functools import wraps
defproxy_function(name, f):
@wraps(f)defproxied_f(*args, **kwargs):
print('Proxying function:', name)
return f(*args, **kwargs)
return proxied_f
defproxy_object(obj):
classProxy:
def__getattr__(self, name):
print('Proxying getattr:', name)
returngetattr(obj, name)
def__hasattr__(self, name):
print('Proxying hasattr:', name)
returnhasattr(obj, name)
def__setattr__(self, name, value):
print('Proxying setattr:', name, '=', repr(value))
setattr(obj, name, value)
def__delattr__(self, name):
print('Proxying delattr:', name)
delattr(obj, name)
for name, f in obj.__class__.__dict__.items():
# don't try to overwrite __class__, __getattr__, etc.ifcallable(f) and name notin Proxy.__dict__:
f = proxy_function(name, f)
setattr(Proxy, name, f)
return Proxy()
Usage:
>>> classFoo:
... def__add__(self, other):
... return'Adding with ' + repr(other)
... >>> foo = Foo()
>>> proxy_foo = proxy_object(foo)
>>> foo + 5'Adding with 5'>>> proxy_foo + 5
Proxying function: __add__
'Adding with 5'
Post a Comment for "List Of All Python Dunder Methods - Which Ones Do You Need To Implement To Correctly Proxy An Object?"