Convert hash to struct

Steven D'Aprano steve at REMOVETHIS.cybersource.com.au
Sat Jun 20 16:26:20 CEST 2009


Jason wrote:

> Here's my general-purpose solution for doing this:
> 
> class Dict2Class(object):
>     """
>     Update like a dictionary, but expose the keys as class properties.

I'm afraid that's wrong. It's wrong twice:

* Properties are computed attributes. These are not, they are regular
attributes.

* Class attributes are shared between all instances. These are not, so they
are instance attributes (or just regular "attributes" without
qualification), not class attributes.



>     def __init__(self, *e, **f):
>         self.__dict__ = dict(*e, **f)

You're updating the instance __dict__, not the class __dict__. Hence they
are instance attributes.

This is the correct thing to do, but if you wanted to share keys and values
between all instances, you would use class attributes:

def __init__(self, *e, **f):
    self.__class__.__dict__ = dict(*e, **f)



As far as properties, in this case there's no sensible reason for making
them properties. (Properties have their uses, but this isn't one of them.)
However, since I'm not sensible *grin*, here's a quick-and-dirty version
that works, for some definition of "works":

class Dict2PropertyClass(object):
    # Like Dict2Class except using properties.
    def __init__(self, *e, **f):
        for key, value in dict(*e, **f).items():
            private = '_' + key
            setattr(self, private, value)
            getter = lambda self, private=private: getattr(self, private)
            setter = (
              lambda self, value, private=private: 
              setattr(self, private, value)
              )
            setattr(self.__class__, key, 
                property(getter, setter)
            )


Getting update() working with this version is left as an exercise for the
masochistic *wink*



-- 
Steven




More information about the Python-list mailing list