pythonpython-3.xdictionaryhttpresponsepython-attrs

Instantiate attrs class from dict with superfluous key/value pairs


I decorated a class using attrs.define and added all important attributes/fields.

import attrs

@attrs.define
class MyAttrsClass:
    important1 = attrs.field(type = int)
    important2 = attrs.field(type = str)
    [...]

Now I would like to initialize instances of that class from a dict. So what I do is calling the contructor with a dict-unpacking.

test_dict = {'important1': 100, 'important2': 'foo'}
ci = MyAttrsClass(**test_dict)

This works in that simple example case, because I specify the same fields in the dict as well as in the MyAttrsClass class.

However, in the real scenario the dict is a deserialized response from a web-api (using json.loads) and it returns many key-value-pairs I'm not interested in, despite the important ones. Then, I get the following error TypeError: MyAttrsClass.__init__() got an unexpected keyword argument 'XYZ'.

Is is possible to initialize an instance of MyAttrsClass, though? I would like to discard the superfluous elements. Do I need to manually remove entries from the input dict or is there a better way using attrs.


Solution

  • I'm an attrs maintainer and the author of cattrs. You should probably just use cattrs since it was designed for cases like this.

    from cattrs import structure
    
    structure(big_dict, MyAttrsClass)
    

    Otherwise, you'll have to do a little preprocessing yourself, as others have mentioned.