I want to apply a decorator to every method in a class. I don't have source code of the class, so I can't directly apply the decorator. I want to call some function that accepts the class and adds the decorators.
But the problem is testclass.__dict__
is a mappingproxy
object and it doesn't support any assignment or modification, directly at least. So the question is how to avoid that restriction and apply decorator?
Here is code of the failed attempt:
class qwer:
def test(self):
print('test')
def decor(func):
def w(*args, **named_args):
print('decor')
func(*args, **named_args)
return w
qwer.__dict__['test'] = decor(qwer.__dict__['test'])
Error:
TypeError: 'mappingproxy' object does not support item assignment
__dict__ in Python represents a dictionary or any mapping object that is used to store the attributes of the object. They are also known as mappingproxy objects.
A mappingproxy is simply a dict with no __setattr__ method. You can check out and refer to this code. from types import MappingProxyType d={'key': "value"} m = MappingProxyType(d) print(type(m)) # <class 'mappingproxy'> m['key']='new' #TypeError: 'mappingproxy' object does not support item assignment.
Use setattr
to set an attribute on a class:
>>> setattr(qwer, 'test', decor(qwer.__dict__['test']))
>>> qwer.test
<function decor.<locals>.w at 0xb5f10e3c>
Demo:
>>> class A:
pass
...
>>> A.__dict__['foo'] = 'bar'
Traceback (most recent call last):
File "<ipython-input-117-92c06357349d>", line 1, in <module>
A.__dict__['foo'] = 'bar'
TypeError: 'mappingproxy' object does not support item assignment
>>> setattr(A, 'foo', 'bar')
>>> A.foo
'bar'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With