167 votes

Comment utiliser la notation du point pour le dict en python ?

Je suis très novice en matière de python et j'aimerais pouvoir faire . pour accéder aux valeurs d'un dict .

Disons que j'ai test comme ça :

>>> test = dict()
>>> test['name'] = 'value'
>>> print(test['name'])
value

Mais j'aimerais pouvoir faire test.name pour obtenir value . En fait, je l'ai fait en remplaçant l'option __getattr__ dans ma classe comme ceci :

class JuspayObject:

    def __init__(self,response):
        self.__dict__['_response'] = response

    def __getattr__(self,key): 
        try:
            return self._response[key]
        except KeyError,err:
            sys.stderr.write('Sorry no key matches')

et ça marche ! quand je le fais :

test.name // I get value.

Mais le problème est que lorsque j'imprime juste test seul j'obtiens l'erreur comme :

'Sorry no key matches'

Pourquoi cela se produit-il ?

5voto

secsilm Points 47

Vous pouvez utiliser la méthode intégrée argparse.Namespace() :

import argparse

args = argparse.Namespace()
args.name = 'value'

print(args.name)
# 'value'

Vous pouvez également obtenir le dict original via vars(args) .

4voto

James Hirschorn Points 31

J'utilise le dotted_dict paquet :

>>> from dotted_dict import DottedDict
>>> test = DottedDict()
>>> test.name = 'value'
>>> print(test.name)
value

4voto

Tudor Corcimar Points 46

Voici un exemple simple et pratique d'aide à la notation par points qui utilise des éléments imbriqués :

def dict_get(data:dict, path:str, default = None):
    pathList = re.split(r'\.', path, flags=re.IGNORECASE)
    result = data
    for key in pathList:
        try:
            key = int(key) if key.isnumeric() else key 
            result = result[key]
        except:
            result = default
            break

    return result

Exemple d'utilisation :

my_dict = {"test1": "str1", "nested_dict": {"test2": "str2"}, "nested_list": ["str3", {"test4": "str4"}]}
print(dict_get(my_dict, "test1"))
# str1
print(dict_get(my_dict, "nested_dict.test2"))
# str2
print(dict_get(my_dict, "nested_list.1.test4"))
# str4

3voto

Aya Points 13144

Vous devez être prudent lorsque vous utilisez __getattr__ car il est utilisé pour de nombreuses fonctionnalités intégrées de Python.

Essayez quelque chose comme ça...

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>

2voto

FoGyuri Points 11

Avec un petit ajout à cette réponse vous pouvez également prendre en charge des listes :

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))
        elif isinstance(value, list):
            self.__setattr__(key, map(NestedNamespace, value))
        else:
            self.__setattr__(key, value)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X