How to access items of dictionary as attributes an

2020-04-23 03:38发布

Following is my requirement which is to be implemented in python: I have a dictionary called context which will be updated from various parts of the program.

Now I have to create an obj called env which holds the dictionary context and environmental variables dictionary also.

env object should have all features of dictionary class along with it, it should be possible to the access the item of dictionary as attribute of the object.

For example,

context = {'install_path' : '/home/xyz','cwd' : '/home/xyz/Desktop'}

the

context dictionary will be updated from various parts of program.

Now I have to create env object which holds context dictionary and also environmental dictionary. And It should be possible to access the items of dictionary as attributes of env object.

For example:

print(env.install_path) # accessing item of context dictionary
print(env.os) #accessing environmental variable print(env)
print(env['install_path'])
print(env)

should produce output as:

 /home/xyz linux 
 /home/xyz
 {'install_path':'/home/xyz','cwd':'/home/xyz/Desktop'}
 all envrionmental variables

Later when the context dictionary is updated the env object should also be updated.

Please help how to achieve this.

标签: python
3条回答
我命由我不由天
2楼-- · 2020-04-23 03:48

Create a subclass of dict.

Objects have methods that get called if an attribute is missing. You can override the default implementation of these methods to do dictionary get and set operations.

class AttributeDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

Previous discussion here

If you need to create a new AttributeDict from an existing dictionary, you can use the following:

context = {'install_path' : '/home/xyz','cwd' : '/home/xyz/Desktop'}
new_dict = AttributeDict(context)
print new_dict.install_path

If you want a different object that just references an existing dictionary, use this

class ReferencedDict(object):
    def __init__(self, reference):
        self.ref = reference
    def __getattr__(self, value):
        return self.ref[value]

env = ReferencedDict(context)
print(env)
查看更多
Deceive 欺骗
3楼-- · 2020-04-23 03:57

Something like this should do the trick:

class DictWithReference(dict):

    def __init__(self, *args, **kwargs):
        self._ref_other = kwargs.pop("ref", {})
        super(DictWithReference, self).__init__(*args, **kwargs)

    def __getattr__(self, attr):
        return self.__getitem__(attr)

    def __getitem__(self, key):
        try:
            return super(DictWithReference, self).__getitem__(attr)
        except KeyError:
            return self._ref_other[attr]

Usage:

>>> context = {'install_path' : '/home/xyz','cwd' : '/home/xyz/Desktop'}
>>> env = DictWithReference({'foo': 'bar'}, ref=context)
>>> env.foo
'bar'
>>> env['foo']
'bar'
>>> env.install_path
'/home/xyz'
>>> env['install_path']
'/home/xyz'
查看更多
够拽才男人
4楼-- · 2020-04-23 04:03

This is the simplest way to do something like that I've seen:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

if __name__ == '__main__':
    o = AttrDict(x=10)
    o.y = 20
    o['z'] = 30
    print o.x, o['y'], o.z

Output:

10 20 30
查看更多
登录 后发表回答