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

如何使用点"." 访问字典成员?

如何解决《如何使用点"."访问字典成员?》经验,为你挑选了11个好方法。

如何通过点"."访问Python字典成员?

例如,mydict['val']我不想写作,而是写作mydict.val.

此外,我想以这种方式访问​​嵌套的dicts.例如

mydict.mydict2.val 

会参考

mydict = { 'mydict2': { 'val': ... } }

derek73.. 219

我一直把它保存在一个util文件中.您也可以在自己的课程中使用它作为mixin.

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

mydict = {'val':'it works'}
nested_dict = {'val':'nested works too'}
mydict = dotdict(mydict)
mydict.val
# 'it works'

mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'nested works too'

@tmthyjames你可以简单地在getter方法中返回dotdict类型对象以递归方式访问带点符号的属性,如:```python class DotDict(dict):"""dot.notation访问字典属性"""def __getattr __(*args ):val = dict.get(*args)如果type(val)是dict,则返回DotDict(val),否则val __setattr__ = dict .__ setitem__ __delattr__ = dict .__ delitem__``` (13认同)

+1表示简单.但似乎不适用于嵌套的dicts.`d = {'foo':{'bar':'baz'}}; d = dotdict(d); d.foo.bar`抛出一个属性错误,但``d.foo`工作正常. (7认同)

非常简单的答案,太棒了!你碰巧知道我需要做什么才能在IPython工作中完成制表工作吗?该类需要实现__dir __(self),但不知怎的,我无法让它工作. (4认同)

经过实验,`get`的确是个坏主意,因为它会返回`None`而不是因为缺少项目而引发错误... (3认同)

是的,这不适用于复杂的嵌套结构. (2认同)


epool.. 127

你可以使用我刚刚创建的这个类来完成它.使用此类,您可以Map像使用另一个字典(包括json序列化)或使用点表示法一样使用该对象.我希望能帮助你:

class Map(dict):
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self[k] = v

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

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

用法示例:

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']

为了处理Python 3,我将`.iteritems()`更新为`.items()` (16认同)

请注意,这将与普通期望的行为不同,因为如果该属性不存在,它将不会引发"AttributeError".相反,它会返回`None`. (9认同)

您可以将构造函数简化为`self.update(*args,**kwargs)`.另外,你可以添加`__missing __(self,key):value = self [key] = type(self)(); 返回值`.然后,您可以使用点表示法添加缺少的条目.如果你想要它是可选择的,你可以添加`__getstate__`和`__setstate__` (4认同)


Chris Redfor.. 100

dotmap通过安装pip

pip install dotmap

它完成了你想要它做的一切和子类dict,所以它像普通的字典一样运行:

from dotmap import DotMap

m = DotMap()
m.hello = 'world'
m.hello
m.hello += '!'
# m.hello and m['hello'] now both return 'world!'
m.val = 5
m.val2 = 'Sam'

最重要的是,您可以将它转换为dict对象:

d = m.toDict()
m = DotMap(d) # automatic conversion in constructor

这意味着如果您要访问的内容已经在dict表单中,您可以将其转换DotMap为便于访问:

import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city

最后,它会自动创建新的子DotMap实例,以便您可以执行以下操作:

m = DotMap()
m.people.steve.age = 31

与束的比较

完全披露:我是DotMap的创建者.我创建它因为Bunch缺少这些功能

记住订单项是按顺序添加和迭代的

自动子项DotMap创建,当您拥有大量层次结构时,可以节省时间并使代码更清晰

从a构造dict并递归地将所有子dict实例转换为DotMap


Kugel.. 56

从dict派生并实现__getattr____setattr__.

或者你可以使用非常相似的束.

我不认为monkeypatch内置的dict类是可能的.



1> derek73..:

我一直把它保存在一个util文件中.您也可以在自己的课程中使用它作为mixin.

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

mydict = {'val':'it works'}
nested_dict = {'val':'nested works too'}
mydict = dotdict(mydict)
mydict.val
# 'it works'

mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'nested works too'


@tmthyjames你可以简单地在getter方法中返回dotdict类型对象以递归方式访问带点符号的属性,如:```python class DotDict(dict):"""dot.notation访问字典属性"""def __getattr __(*args ):val = dict.get(*args)如果type(val)是dict,则返回DotDict(val),否则val __setattr__ = dict .__ setitem__ __delattr__ = dict .__ delitem__```
+1表示简单.但似乎不适用于嵌套的dicts.`d = {'foo':{'bar':'baz'}}; d = dotdict(d); d.foo.bar`抛出一个属性错误,但``d.foo`工作正常.
非常简单的答案,太棒了!你碰巧知道我需要做什么才能在IPython工作中完成制表工作吗?该类需要实现__dir __(self),但不知怎的,我无法让它工作.
经过实验,`get`的确是个坏主意,因为它会返回`None`而不是因为缺少项目而引发错误...
是的,这不适用于复杂的嵌套结构.

2> epool..:

你可以使用我刚刚创建的这个类来完成它.使用此类,您可以Map像使用另一个字典(包括json序列化)或使用点表示法一样使用该对象.我希望能帮助你:

class Map(dict):
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self[k] = v

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

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

用法示例:

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']


为了处理Python 3,我将`.iteritems()`更新为`.items()`
请注意,这将与普通期望的行为不同,因为如果该属性不存在,它将不会引发"AttributeError".相反,它会返回`None`.
您可以将构造函数简化为`self.update(*args,**kwargs)`.另外,你可以添加`__missing __(self,key):value = self [key] = type(self)(); 返回值`.然后,您可以使用点表示法添加缺少的条目.如果你想要它是可选择的,你可以添加`__getstate__`和`__setstate__`

3> Chris Redfor..:

dotmap通过安装pip

pip install dotmap

它完成了你想要它做的一切和子类dict,所以它像普通的字典一样运行:

from dotmap import DotMap

m = DotMap()
m.hello = 'world'
m.hello
m.hello += '!'
# m.hello and m['hello'] now both return 'world!'
m.val = 5
m.val2 = 'Sam'

最重要的是,您可以将它转换为dict对象:

d = m.toDict()
m = DotMap(d) # automatic conversion in constructor

这意味着如果您要访问的内容已经在dict表单中,您可以将其转换DotMap为便于访问:

import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city

最后,它会自动创建新的子DotMap实例,以便您可以执行以下操作:

m = DotMap()
m.people.steve.age = 31

与束的比较

完全披露:我是DotMap的创建者.我创建它因为Bunch缺少这些功能

记住订单项是按顺序添加和迭代的

自动子项DotMap创建,当您拥有大量层次结构时,可以节省时间并使代码更清晰

从a构造dict并递归地将所有子dict实例转换为DotMap



4> Kugel..:

从dict派生并实现__getattr____setattr__.

或者你可以使用非常相似的束.

我不认为monkeypatch内置的dict类是可能的.


正确.你不能monkeypatch`dict`(感谢上帝).
Monkeypatching使用Python(或任何语言)的动态性来改变通常在源代码中定义的东西.它特别适用于在创建类之后更改类的定义.
猴子补丁到底是什么意思?我听说过但没用过。(很抱歉,我问这样的新手问题,我编程方面还不太好(我才是二年级学生。)

5> tdihp..:

我试过这个:

class dotdict(dict):
    def __getattr__(self, name):
        return self[name]

你也可以试试__getattribute__.

使每个dict成为一种dotdict就足够了,如果你想从多层dict中初始化它,也可以尝试实现__init__.



6> Dave..:

Fabric有一个非常好的,最小的实现.扩展它以允许嵌套访问,我们可以使用a defaultdict,结果看起来像这样:

from collections import defaultdict

class AttributeDict(defaultdict):
    def __init__(self):
        super(AttributeDict, self).__init__(AttributeDict)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(key)

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

按如下方式使用它:

keys = AttributeDict()
keys.abc.xyz.x = 123
keys.abc.xyz.a.b.c = 234

这详细阐述了库格尔的"从字典中__getattr____setattr__得出并实施"的回答.现在你知道了!



7> Mike Graham..:

别.属性访问和索引是Python中的独立事物,您不应该希望它们执行相同的操作.namedtuple如果你有一些应该具有可访问属性的东西并使用[]符号从dict中获取一个项目,那么创建一个类(可能由一个类创建).


如果它对JavaScript来说足够好,为什么不用Python呢?
你已经知道了很好的Python风格:我们告诉你,不要假装dict的值是属性.这是不好的做法.例如,如果要存储与dict的现有属性同名的值,例如"items"或"get"或"pop",该怎么办?可能令人困惑的事情.所以不要这样做!
哎呀,我忘记了'items','get'或'pop等属性.感谢您提出这个重要的例子!
@Gabe,已经很久了......但我认为值得一提.它在JS中并不"足够好":它在JS中"足够糟糕".当你存储与原型链中其他重要属性同名的keys/attr时会很有趣.
我可以看到一个用例;实际上,我是在几周前完成的。就我而言,我想要一个可以使用点表示法访问属性的对象。我发现简单地从dict继承非常容易,因此我获得了所有dict内置的功能,但是此对象的公共接口使用点符号(本质上是一些静态数据的只读接口)。我的用户使用'foo.bar'比使用'foo [“ bar”]'更快乐,并且我很高兴可以支持dict数据类型的功能。

8> volodymyr..:

如果你想修改你修改过的字典,你需要在上面的答案中添加一些状态方法:

class DotDict(dict):
    """dot.notation access to dictionary attributes"""
    def __getattr__(self, attr):
        return self.get(attr)
    __setattr__= dict.__setitem__
    __delattr__= dict.__delitem__

    def __getstate__(self):
        return self

    def __setstate__(self, state):
        self.update(state)
        self.__dict__ = self



9> M J..:

在Kugel的回答的基础上,考虑到Mike Graham的谨慎言辞,如果我们制作一个包装器怎么办?

class DictWrap(object):
  """ Wrap an existing dict, or create a new one, and access with either dot 
    notation or key lookup.

    The attribute _data is reserved and stores the underlying dictionary.
    When using the += operator with create=True, the empty nested dict is 
    replaced with the operand, effectively creating a default dictionary
    of mixed types.

    args:
      d({}): Existing dict to wrap, an empty dict is created by default
      create(True): Create an empty, nested dict instead of raising a KeyError

    example:
      >>>dw = DictWrap({'pp':3})
      >>>dw.a.b += 2
      >>>dw.a.b += 2
      >>>dw.a['c'] += 'Hello'
      >>>dw.a['c'] += ' World'
      >>>dw.a.d
      >>>print dw._data
      {'a': {'c': 'Hello World', 'b': 4, 'd': {}}, 'pp': 3}

  """

  def __init__(self, d=None, create=True):
    if d is None:
      d = {}
    supr = super(DictWrap, self)  
    supr.__setattr__('_data', d)
    supr.__setattr__('__create', create)

  def __getattr__(self, name):
    try:
      value = self._data[name]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[name] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

  def __setattr__(self, name, value):
    self._data[name] = value  

  def __getitem__(self, key):
    try:
      value = self._data[key]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[key] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

  def __setitem__(self, key, value):
    self._data[key] = value

  def __iadd__(self, other):
    if self._data:
      raise TypeError("A Nested dict will only be replaced if it's empty")
    else:
      return other



10> Senthil..:

我喜欢Munch,它在点访问的基础上提供了许多方便的选择。

进口午餐

temp_1 = {'person':{'fname':'senthil','lname':'ramalingam'}}

dict_munch = munch.munchify(temp_1)

dict_munch.person.fname



11> IRSHAD..:

使用__getattr__非常简单,可在Python 3.4.3中使用

class myDict(dict):
    def __getattr__(self,val):
        return self[val]


blockBody=myDict()
blockBody['item1']=10000
blockBody['item2']="StackOverflow"
print(blockBody.item1)
print(blockBody.item2)

输出:

10000
StackOverflow

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