Search code examples
pythonsetattributesetattr

Python setattr() can't find attribute that obviously exists


I'm at my wits end. Can't find anything else that helps with this.

dta = {'type': "", 'content': ""}
print dta

>>>{'content': '', 'type': ''}

setattr(dta, 'type', "Steve")

>>>AttributeError: 'dict' object has no attribute 'type'


Solution

  • Python's dictionaries aren't JS objects. When you create a dict, you aren't creating a dynamic object whose properties you can change at runtime as in JS. Instead the dictionary knows how to store pairs of keys and values and does so by overriding the operator [] (def __getitem__(self, key)).

    On a more implementation level - calling getattr / setattr is really a shorthand for data.__getattr__("foo") and since dict uses __getitem__ as opposed to __getattr__ the function call fails.

    Thus, there's no way to set (or get for that matter) the dict's items using generic attribute functions.

    However, you can create your custom dict class that does support that operation (although I wouldn't recommend it):

    class AttrDict(dict):
        def __init__(self):
            dict.__init__(self)
    
        # Override getattr and setattr so that they return the values of getitem / setitem
        def __setattr__(self, name, value):
            self[name] = value
    
        def __getattr__(self, name):
            return self[name]
    
    data = AttrDict()
    data["foo"] = "bar"
    print(getattr(data, "foo"))