简体   繁体   中英

Classes vs Dictionaries in Python for storing key-value pairs

I need to define some key-value parameters to configure the behaviour of a class. My requirements are two:

  • To be able to process them programatically
  • To be able to make more specific configurations that overwrite some of the values.

The natural approach for the first requirement is to use a dict (so I can loop over keys, values or items with a for loop), but for the second requirement it seems more appropriate to use a class hierarchy and let the attribute lookup mechanism to do the work (plus I get other goodies like being able to use properties for some values).

Is there a way to get best of both worlds?


After reading the comments, It does not need to be mutable (I won't be changing the values of an already created instance), it's just for static configuration. But I might need to add new values in a more specific instance.

I think in the end I could just use a dict.copy + dict.update for the specific instances (I can live without the properties).

Somehow along the lines of what suggested in the commment by Fabio, I would remark that the two are not mutually exclusive, given that in Python [nearly] everything is an object (including classes!).

One obvious solution is - again quoting Fabio - subclassing a dict . The other would be make your own class starting from the collections.abc containers (using an abstract base class ( abc ) is not a requirement, but would probably the most pythonic way to implement your own container from scratch).

HTH!

If you can use python 3.3 ChainMap is exactly what you want.

http://docs.python.org/3.3/library/collections#collections.ChainMap

It's basically a list of dictionaries and will look for a given key in each one sequentially until a match is found.

Actually, here's the code to use it in 2.7:

http://code.activestate.com/recipes/305268-chained-map-lookups/

is this what you need?

class my_dict(dict):
    def __getattr__(self, name):
        return self[name]
    def __setattr__(self, name, value):
        self[name] = value

d = my_dict()
d.key = "value"
print d.key       #>>>value

for k,v in d.items():
    print k,v     #>>>key value

You could just use named tuples . See here and the accepted answer on this question for a nice introduction to them. Some important points from that answer are:

  • They were added in Python 2.6 and Python 3.0, although there is a recipe for implementation in Python 2.4.

  • Named tuples are backwards compatible with normal tuples

Also, named tuples have a number of useful methods such as _fields to get the names of the used and an _asdict method which returns an (ordered) dict of the named tuple contents.

Here's my take:

class Config(object):
    def _keys(self):
        return (name for name in dir(self) if not name.startswith('_'))
    __iter__ = _keys

    def _values(self):
        return (getattr(self, name) for name in self)

    def _items(self):
        return ((name, getattr(self, name)) for name in self)

>>> class Foo(Config):
...     bar = 3
...     baz = 'spam'
...
>>> class Sub(Foo):
...     bar = 4
...
>>> x = Sub()
>>> list(x._items())
[('bar', 4), ('baz', 'spam')]
>>>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM