【问题标题】:How to access items of dictionary as attributes and vice versa [duplicate]如何将字典项目作为属性访问,反之亦然[重复]
【发布时间】:2013-02-12 20:51:35
【问题描述】:

以下是我要在 python 中实现的要求: 我有一个名为 context 的字典,它将从程序的各个部分更新。

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

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

例如,

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

context 字典将从程序的各个部分更新。

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

例如:

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

应该产生如下输出:

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

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

请帮助如何实现这一点。

【问题讨论】:

  • 这是可能的,但你为什么要允许这个?它只会让事情变得更混乱——而不是更容易......
  • @JonClements:要求就是这样
  • 嗯,如果一个变量被称为updatepopgetkeysitems等等会发生什么...?
  • @JonClements:所有人都应该按照他们的共同行为按预期工作
  • @WesleyBaugh 这就是我的想法——只是想弄清楚问题是否还有其他问题。但是,是的 - OP 应该阅读它并查看它是否符合他们的要求。

标签: python


【解决方案1】:

创建 dict 的子类。

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

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

之前的讨论here

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

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

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

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

env = ReferencedDict(context)
print(env)

【讨论】:

  • 我测试了这个答案,但它并没有满足我的所有要求。我有一个已经创建的字典,我必须创建一个包含上下文字典和环境字典的对象。另外@ 987654325@ 也应该可以工作
  • 具体没有涵盖哪些要求?
  • print(env) 这应该显示context 字典的内容以及环境字典
  • @vinaysurve:用两个AttributeDicts、envcontext 创建一个对象并不是一个巨大的概念飞跃。有什么问题?
  • @JoelCornett:似乎一切正常。但是当我在 context 字典中添加一些项目时,这并没有反映在 env 对象中
【解决方案2】:

这样的事情应该可以解决问题:

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]

用法:

>>> 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'

【讨论】:

    【解决方案3】:

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

    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
    

    输出:

    10 20 30
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-28
      • 2011-06-24
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      相关资源
      最近更新 更多