关于python:如何访问字典项作为属性,反之亦然

How to access items of dictionary as attributes and vice versa

本问题已经有最佳答案,请猛点这里访问。

下面是我在python中要实现的需求:我有一本叫做上下文的字典,它将从程序的各个部分更新。

现在我必须创建一个名为env的obj,它还保存字典上下文和环境变量字典。

env对象应具有字典类的所有特性,并可以访问字典项作为对象的属性。

例如,

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

这个

context
dictionary will be updated from various parts of program.

现在我必须创建一个包含上下文字典和环境字典的env对象。应该可以访问字典中作为env对象属性的条目。

例如:

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

应产生如下输出:

1
2
3
4
 /home/xyz linux
 /home/xyz
 {'install_path':'/home/xyz','cwd':'/home/xyz/Desktop'}
 all envrionmental variables

稍后,当更新上下文字典时,还应更新env对象。

请帮助实现这一点。


这是我见过的最简单的方法:

1
2
3
4
5
6
7
8
9
10
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

输出:

1
10 20 30

像这样的方法应该可以做到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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]

用途:

1
2
3
4
5
6
7
8
9
10
>>> 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'


创建dict的子类。

对象具有在缺少属性时被调用的方法。您可以重写这些方法的默认实现来执行字典获取和设置操作。

1
2
3
4
5
class AttributeDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

此处显示上一个讨论

如果需要从现有字典创建新的attributedict,可以使用以下内容:

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

如果您想要一个引用现有字典的不同对象,请使用此

1
2
3
4
5
6
7
8
class ReferencedDict(object):
    def __init__(self, reference):
        self.ref = reference
    def __getattr__(self, value):
        return self.ref[value]

env = ReferencedDict(context)
print(env)