Accessing dict keys like an attribute?

前端 未结 27 2110
南笙
南笙 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: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
    

提交回复
热议问题