How to use dot notation for dict in python?

后端 未结 7 1484
醉话见心
醉话见心 2020-11-29 20:44

I\'m very new to python and I wish I could do . notation to access values of a dict.

Lets say I have test like this:

相关标签:
7条回答
  • 2020-11-29 21:21

    Could you use a named tuple?

    from collections import namedtuple
    Test = namedtuple('Test', 'name foo bar')
    my_test = Test('value', 'foo_val', 'bar_val')
    print(my_test)
    print(my_test.name)
    

    0 讨论(0)
  • 2020-11-29 21:23

    You have to be careful when using __getattr__, because it's used for a lot of builtin Python functionality.

    Try something like this...

    class JuspayObject:
    
        def __init__(self,response):
            self.__dict__['_response'] = response
    
        def __getattr__(self, key):
            # First, try to return from _response
            try:
                return self.__dict__['_response'][key]
            except KeyError:
                pass
            # If that fails, return default behavior so we don't break Python
            try:
                return self.__dict__[key]
            except KeyError:
                raise AttributeError, key
    
    >>> j = JuspayObject({'foo': 'bar'})
    >>> j.foo
    'bar'
    >>> j
    <__main__.JuspayObject instance at 0x7fbdd55965f0>
    
    0 讨论(0)
  • 2020-11-29 21:27

    Add a __repr__() method to the class so that you can customize the text to be shown on

    print text
    

    Learn more here: https://web.archive.org/web/20121022015531/http://diveintopython.net/object_oriented_framework/special_class_methods2.html

    0 讨论(0)
  • 2020-11-29 21:33

    I assume that you are comfortable in Javascript and want to borrow that kind of syntax... I can tell you by personal experience that this is not a great idea.

    It sure does look less verbose and neat; but in the long run it is just obscure. Dicts are dicts, and trying to make them behave like objects with attributes will probably lead to (bad) surprises.

    If you need to manipulate the fields of an object as if they were a dictionary, you can always resort to use the internal __dict__ attribute when you need it, and then it is explicitly clear what you are doing. Or use getattr(obj, 'key') to have into account the inheritance structure and class attributes too.

    But by reading your example it seems that you are trying something different... As the dot operator will already look in the __dict__ attribute without any extra code.

    0 讨论(0)
  • 2020-11-29 21:39

    In addition to this answer, one can add support for nested dicts as well:

    from types import SimpleNamespace
    
    class NestedNamespace(SimpleNamespace):
        def __init__(self, dictionary, **kwargs):
            super().__init__(**kwargs)
            for key, value in dictionary.items():
                if isinstance(value, dict):
                    self.__setattr__(key, NestedNamespace(value))
                else:
                    self.__setattr__(key, value)
    
    nested_namespace = NestedNamespace({
        'parent': {
            'child': {
                'grandchild': 'value'
            }
        },
        'normal_key': 'normal value',
    })
    
    
    print(nested_namespace.parent.child.grandchild)  # value
    print(nested_namespace.normal_key)  # normal value
    

    Note that this does not support dot notation for dicts that are somewhere inside e.g. lists.

    0 讨论(0)
  • 2020-11-29 21:40

    This functionality already exists in the standard libraries, so I recommend you just use their class.

    >>> from types import SimpleNamespace
    >>> d = {'key1': 'value1', 'key2': 'value2'}
    >>> n = SimpleNamespace(**d)
    >>> print(n)
    namespace(key1='value1', key2='value2')
    >>> n.key2
    'value2'
    

    Adding, modifying and removing values is achieved with regular attribute access, i.e. you can use statements like n.key = val and del n.key.

    To go back to a dict again:

    >>> vars(n)
    {'key1': 'value1', 'key2': 'value2'}
    

    The keys in your dict should be string identifiers for attribute access to work properly.

    Simple namespace was added in Python 3.3. For older versions of the language, argparse.Namespace has similar behaviour.

    0 讨论(0)
提交回复
热议问题