Skip to content Skip to sidebar Skip to footer

Adding Fields To A Class Via Setattr Vs. Storing A Dictionary In Python

I have a class called User: class User(object): def __init__(self, arg1, ..., traits = None): self.arg1 = arg1 ... self.traits = traits User has a pro

Solution 1:

Looks fine to me, I would be tempted to re-write as:

classUser(object):def__init__(self, arg1, arg2, **traits):
        self.arg1 = arg1
        self.arg2 = arg2
        self.traits = traits

If you really wanted, you could then override to fall back on the traits dictionary if an attribute can't be found:

def__getattr__(self, name):
    returnself.traits[name]

Example:

>>> u = User(1, 2, email='something')
>>> y = User(1, 2, email='bob', telno='999')
>>> u.arg1, u.arg2, u.email
(1, 2, 'something')
>>> y.arg1, y.arg2, y.email, y.telno
(1, 2, 'bob', '999')
>>> y.arg1, y.arg2, y.email, y.something
Traceback (most recent call last):
  File "<pyshell#105>", line 1, in <module>
    y.arg1, y.arg2, y.email, y.something
  File "/home/jon/adfafasdf.py", line 7, in __getattr__
    return self.traits[name]
KeyError: 'something'

So you may wish to make that a more sensible error, and change to:

def__getattr__(self, name):
    try:
        return self.traits[name]
    except KeyError as e:
        raise AttributeError() # with suitably formatted string

Solution 2:

You can modify the instance's __dict__ directly (assuming that it doesn't implement __slots__ or anything silly like that)

Here's a simple example:

classTraits(object):
    passclassUser(object):
    def__init__(self,**traits):
        self.traits = Traits()
        self.traits.__dict__.update(traits)

a = User(eye_color="blue")
print a.traits.eye_color

Of course, it is probaby safer (but slightly less efficient) to just do:

class User(object):
    def __init__(self,**traits):
        self.traits = Traits()
        for k,v in traits.items():
            setattr(traits,k,v)

which is really only 1 additional line of code to provide the same API. It's safer because you never know what someone did to mess with Traits to provide various descriptors (e.g. property) etc. setattr will do all of that stuff correctly where blindly writing to __dict__ could be potentially harmful.

Post a Comment for "Adding Fields To A Class Via Setattr Vs. Storing A Dictionary In Python"