Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to modify class __dict__ (a mappingproxy)? [duplicate]

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
like image 278
DartLenin Avatar asked Nov 16 '13 14:11

DartLenin


People also ask

What is __ dict __ in Python?

__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.

What is Mappingproxy?

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.


1 Answers

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'
like image 157
Ashwini Chaudhary Avatar answered Oct 03 '22 11:10

Ashwini Chaudhary