当前位置:  开发笔记 > 编程语言 > 正文

Python使字典项可作为对象属性访问

如何解决《Python使字典项可作为对象属性访问》经验,为你挑选了2个好方法。

这主要是语法糖,但我想访问字典中的项目作为对象属性.

例:

class CoolThing():
  def __init__(self):
    self.CoolDict = {'a': 1, 'b': 2}

而且我想拥有

my_cool_thing.a # => 1
my_cool_thing.b # => 2

编辑:具有带点符号的嵌套结构的潜在解决方案的一些代码:device.property.field

class Parameters():

    def __init__(self, ids, devices):
        self._ids = ids
        self._devices = devices
        for p in self._devices:
            p = p[0]
            if self.__dict__.get(p.device) is None:
                self.__dict__[p.device] = SmartDict()
            else:
                if self.__dict__[p.device].get(p.property) is None:
                    self.__dict__[p.device][p.property] = SmartDict()
                else:
                    if self.__dict__[p.device][p.property].get(p.field) is None:
                        self.__dict__[p.device][p.property][p.field] = ParameterData(p)

class SmartDict():
    def __init__(self):
        self.__dict__ = {}

    def __getitem__(self, k):
        return self.__dict__[k]

    def __setitem__(self, k, v):
        self.__dict__[k] = v

    def get(self, k):
        return self.__dict__.get(k)

    def __len__(self):
        return len(self.__dict__)

Wayne Werner.. 5

你想__getattr____setattr__,但你必须推出自己的类(我不知道任何建宏,不过namedtuple,如果你并不需要太大的变化值可能工作)

class AttrDict(dict):
    def __getattr__(self, attr):
        return self[attr]

    def __setattr__(self, attr, value):
        self[attr] = value

如果您只想以这种方式访问​​子词典,只需更改selfself.cool_dict

class CoolThing:
   def __init__(self):
      self.cool_dict = {'a': 1, 'b': 2}

   def __getattr__(self, attr):
      return self.cool_dict[attr] 

   def __setattr__(self, attr, value):
      # Note, you'll have to do this for anything that you want to set
      # in __init__. 
      if attr == 'cool_dict':
          super().__setattr__(attr, value)
      else:
          self.cool_dict[attr] = value

请注意,任何其他查找失败__getattr__使用,但如果您想确保首先调用您的函数,则可以使用__getattribute__

还要注意的是self.cool_dict上不存在CoolThing后才__init__被调用.我的初始版本将超出最大递归深度,因为当你创建类时,它将self.cool_dict在init,call中设置__setattr__,这将尝试得到self.cool_dict它可以设置[attr] = value它.当然它还没有找到cool_dict,所以它会__getattr__再次尝试再打电话......它无法找到cool_dict并绕过它.

另一个选择是使用类级变量,但这可能根本不是你想要的:)



1> Wayne Werner..:

你想__getattr____setattr__,但你必须推出自己的类(我不知道任何建宏,不过namedtuple,如果你并不需要太大的变化值可能工作)

class AttrDict(dict):
    def __getattr__(self, attr):
        return self[attr]

    def __setattr__(self, attr, value):
        self[attr] = value

如果您只想以这种方式访问​​子词典,只需更改selfself.cool_dict

class CoolThing:
   def __init__(self):
      self.cool_dict = {'a': 1, 'b': 2}

   def __getattr__(self, attr):
      return self.cool_dict[attr] 

   def __setattr__(self, attr, value):
      # Note, you'll have to do this for anything that you want to set
      # in __init__. 
      if attr == 'cool_dict':
          super().__setattr__(attr, value)
      else:
          self.cool_dict[attr] = value

请注意,任何其他查找失败__getattr__使用,但如果您想确保首先调用您的函数,则可以使用__getattribute__

还要注意的是self.cool_dict上不存在CoolThing后才__init__被调用.我的初始版本将超出最大递归深度,因为当你创建类时,它将self.cool_dict在init,call中设置__setattr__,这将尝试得到self.cool_dict它可以设置[attr] = value它.当然它还没有找到cool_dict,所以它会__getattr__再次尝试再打电话......它无法找到cool_dict并绕过它.

另一个选择是使用类级变量,但这可能根本不是你想要的:)


与`__getattribute__`混淆往往是一个错误的好主意.首先是因为它可能很棘手,但也因为它会通过一个明显的因素减慢属性分辨率(至少上次我对这个解决方案进行基准测试时非常明显).

2> Andrea Corbe..:

CoolDict它已经存在,它的名字是__dict__:

>>> class CoolThing(object):
...     def __init__(self):
...         self.__dict__['a'] = 1
...         self.__dict__['b'] = 2
... 
>>> thing = CoolThing()
>>> thing.a
1
>>> thing.b
2
>>> thing.c = 3
>>> thing.__dict__
{'a': 1, 'b': 2, 'c': 3}

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有