Accessing dict keys like an attribute?

前端 未结 27 2107
南笙
南笙 2020-11-22 04:22

I find it more convenient to access dict keys as obj.foo instead of obj[\'foo\'], so I wrote this snippet:

class AttributeDict(dict         


        
相关标签:
27条回答
  • 2020-11-22 05:12

    As noted by Doug there's a Bunch package which you can use to achieve the obj.key functionality. Actually there's a newer version called

    NeoBunch

    It has though a great feature converting your dict to a NeoBunch object through its neobunchify function. I use Mako templates a lot and passing data as NeoBunch objects makes them far more readable, so if you happen to end up using a normal dict in your Python program but want the dot notation in a Mako template you can use it that way:

    from mako.template import Template
    from neobunch import neobunchify
    
    mako_template = Template(filename='mako.tmpl', strict_undefined=True)
    data = {'tmpl_data': [{'key1': 'value1', 'key2': 'value2'}]}
    with open('out.txt', 'w') as out_file:
        out_file.write(mako_template.render(**neobunchify(data)))
    

    And the Mako template could look like:

    % for d in tmpl_data:
    Column1     Column2
    ${d.key1}   ${d.key2}
    % endfor
    
    0 讨论(0)
  • 2020-11-22 05:13

    I created this based on the input from this thread. I need to use odict though, so I had to override get and set attr. I think this should work for the majority of special uses.

    Usage looks like this:

    # Create an ordered dict normally...
    >>> od = OrderedAttrDict()
    >>> od["a"] = 1
    >>> od["b"] = 2
    >>> od
    OrderedAttrDict([('a', 1), ('b', 2)])
    
    # Get and set data using attribute access...
    >>> od.a
    1
    >>> od.b = 20
    >>> od
    OrderedAttrDict([('a', 1), ('b', 20)])
    
    # Setting a NEW attribute only creates it on the instance, not the dict...
    >>> od.c = 8
    >>> od
    OrderedAttrDict([('a', 1), ('b', 20)])
    >>> od.c
    8
    

    The class:

    class OrderedAttrDict(odict.OrderedDict):
        """
        Constructs an odict.OrderedDict with attribute access to data.
    
        Setting a NEW attribute only creates it on the instance, not the dict.
        Setting an attribute that is a key in the data will set the dict data but 
        will not create a new instance attribute
        """
        def __getattr__(self, attr):
            """
            Try to get the data. If attr is not a key, fall-back and get the attr
            """
            if self.has_key(attr):
                return super(OrderedAttrDict, self).__getitem__(attr)
            else:
                return super(OrderedAttrDict, self).__getattr__(attr)
    
    
        def __setattr__(self, attr, value):
            """
            Try to set the data. If attr is not a key, fall-back and set the attr
            """
            if self.has_key(attr):
                super(OrderedAttrDict, self).__setitem__(attr, value)
            else:
                super(OrderedAttrDict, self).__setattr__(attr, value)
    

    This is a pretty cool pattern already mentioned in the thread, but if you just want to take a dict and convert it to an object that works with auto-complete in an IDE, etc:

    class ObjectFromDict(object):
        def __init__(self, d):
            self.__dict__ = d
    
    0 讨论(0)
  • 2020-11-22 05:13
    class AttrDict(dict):
    
         def __init__(self):
               self.__dict__ = self
    
    if __name__ == '____main__':
    
         d = AttrDict()
         d['ray'] = 'hope'
         d.sun = 'shine'  >>> Now we can use this . notation
         print d['ray']
         print d.sun
    
    0 讨论(0)
提交回复
热议问题