Il y a beaucoup de bonnes fonctionnalités de getattr () - comme pour analyser les structures de dictionnaire imbriquées, telles que:
Je voudrais faire un parallèle setattr (). Essentiellement, donné: p> J'aimerais produire une fonction de telle sorte que je puisse attribuer: p> plus ou Moins, cela fonctionnerait de la même manière que: p> à donner: p> Je l'appelle actuellement setbydot () code>: p> Un problème avec ceci est que si une clé au milieu n'existe pas, vous devez vérifier et faire un Touche intermédiaire si elle n'existe pas --- c'est-à-dire pour ce qui précède: p> donc, vous devez d'abord faire: p> Un autre est que la saisie du moment où l'élément suivant est une liste différente de la saisie lorsque l'élément suivant est une chaîne, c'est-à-dire: p> def setByDot(obj,ref,newval):
ref = ref.replace("[",".[")
cmd = ref.split('.')
numkeys = len(cmd)
count = 0
for c in cmd:
count = count+1
while count < numkeys:
if c.find("["):
idstart = c.find("[")
numend = c.find("]")
try:
deep = obj[int(idstart+1:numend-1)]
except:
obj[int(idstart+1:numend-1)] = []
deep = obj[int(idstart+1:numend-1)]
else:
try:
deep = obj[c]
except:
if obj[c] isinstance(dict):
obj[c] = {}
else:
obj[c] = ''
deep = obj[c]
setByDot(deep,c,newval)
4 Réponses :
>>> class D(dict): ... def __missing__(self, k): ... ret = self[k] = D() ... return ret ... >>> x=D() >>> x['f'][0]['a'] = 'whatever' >>> x {'f': {0: {'a': 'whatever'}}}
Hmm, j'aime bien c'est / beaucoup / plus simple, et il est proche, mais X aurait besoin de retourner {"F": [{"A": "Peu importe"}]} code> au lieu de
{'F': {0: {'A': 'Quel que soit'}}} code> où l'intermédiaire est la 0ème d'une liste, au lieu d'une valeur touchée à 0. Je pense que je peux travailler avec ceci, ou Peut-être que l'approche générale de prendre un analyseur dict-à-objet ou quelque chose de ...
Quel devrait x = d (); x ['f'] [100] ['a'] = 'whatevs' code> faire, si c'est une liste au lieu d'une dictionnaire?
Ouais, bon point, mais je suppose que cela nécessiterait de créer des mannequins pour les articles 0 à 99. Aussi bon point que cela pourrait signifier si vous les avez attribués dans la commande x ['F'] ['A'] ['A'] 'whatevs', x ['F'] [99] ['A'] = 'Plus'] = "Plus", vous pouvez écraser toutes les valeurs que vous avez fabriquées pour 99, si vous avez rempli une chaîne vide ou une liste vide, ou vide la dicte vide.
Vous pouvez pirater quelque chose ensemble en fixant deux problèmes:
Donc, le code ressemblera à ceci: p> et la sortie de x et y sera: p> L'astuce consiste à créer une radiographie par défaut d'objets pouvant être un dict ou une liste en fonction de la façon dont vous y accédez.
Donc, lorsque vous avez l'assidation Les deux pavés et la dictorlist sont un peu hacky, mais après toutes les tâches, vous n'avez plus de magie, vous avez une structure de dict et de listes. P> P> x ['f'] [10] ['A'] = 'Quelque chose' code> il fonctionnera la manière suivante: p>
Désolé, je ne comprends pas --- Pouvez-vous me montrer comment cela fonctionne comme un setter, passant de la fonction (x, 'f [10] .a', val) code> à
x ['F'] [10] ['A'] = Val = 'Quelque chose' code>?
Vous pouvez également implémenter la liste matelle en tant que défaut_dict, en supposant que les indices seraient des INT et que __iter__ retournerait des iervalues ().
@DBW J'y ai pensé, mais a préféré utiliser des listes car je ne sais pas comment ça va être utilisé (c'est-à-dire la coupe, le tri ...)
bon point. La notation de la tranche nécessiterait de prolonger la liste, plutôt que de faire une liste de plaide.
Je l'ai séparé en deux étapes. Dans la première étape, la chaîne de requête est décomposée dans une série d'instructions. De cette façon, le problème est découplé, nous pouvons voir les instructions avant de les exécuter, et il n'est pas nécessaire d'appels récursifs. pour votre exemple P> x = []
_setattr(x, "1.4", "asdf")
print x
[{}, {'4': 'asdf'}] # A list, which isn't hashable
>>> y = {"a": "stuff"}
>>> _setattr(y, "f[1.4]", "test") # We're indexing f with 1.4, which is a list!
>>> print y
{'a': 'stuff', 'f': [{}, {'4': 'test'}]}
>>> print _getattr(y, "f[1.4]") # Works for _getattr too
"test"
Cela avait l'air vraiment cool, mais ne semblait pas travailler pour moi. >>> x = {"A": "Stuff"} >>> _SetatTtr (x, "F [0] .a", "Test") >>> x {'A': 'Stuff'} code>
@Mitenchops Pour une raison quelconque, le build_instructions code> que j'ai sauvegardé est différent de ce qui se passe. Je l'ai mis à jour afin que cela fonctionne maintenant.
@MITENCHOPS haha, s'avère que j'avais commuté les arguments dans build_instructions code> par accident. Faites-moi savoir s'il y a toujours des problèmes!
Il est possible de synthétiser des éléments de réglage de récursivement / des attributs en remplacement Je travaille sur une bibliothèque Cela fait quelques choses similaires à cela, alors je travaillais sur une classe qui peut attribuer de manière dynamique ses propres sous-classes à l'instanciation. Cela facilite le travail avec ce type de chose, mais si ce type de piratage vous fait manifester, vous pouvez obtenir un comportement similaire en créant un proxyObject similaire à celui que je crée et en créant les classes individuelles utilisées par le proxyObject de manière dynamique dans la fonction A Fonction. . Quelque chose comme p> Vous pouvez utiliser le dictionnaire comme que j'ai utilisé dans FlexibleObject ci-dessous rendrait cette implémentation de manière significative plus efficace si c'est ainsi que vous le mettez en œuvre. Le code que je fournirai utilise le flexibleObject cependant. À l'heure actuelle, il ne supporte que des cours qui, comme presque toutes les classes intégrées de Python sont capables d'être générés en prenant une instance d'eux-mêmes comme son seul argument à leur puis pour l'utiliser pour utiliser ceci pour synthétiser des attributs et des éléments d'un objet de dictionnaire, vous pouvez faire quelque chose comme ceci: P> __ getItem __ code> pour renvoyer un proxy de retour un proxy pouvant définir une valeur dans la fonction d'origine.
__ init __ code> /
__ nouveau __ code>. Dans la semaine prochaine ou deux, j'ajouterai une assistance pour tout ce qui est piquant et un lien vers un référentiel GitHub qui le contient. Voici le code: p>
>>> qrd = QuickRecursiveDict
>>> qrd[0][13] # returns an instance of a subclass of KeyError
>>> qrd[0][13] = 9
>>> qrd[0][13] # 9
>>> qrd[0][13]['forever'] = 'young'
>>> qrd[0][13] # 9
>>> qrd[0][13]['forever'] # 'young'
>>> qrd[0] # returns an instance of a subclass of KeyError
>>> qrd[0] = 0
>>> qrd[0] # 0
>>> qrd[0][13]['forever'] # 'young'