2012-02-21 3 views
3

Ok donc j'ai construit mon propre gestionnaire variable qui a une fonction __getitem__ à utiliser lors de l'accès aux données via des données [clés], il fonctionne très bien, sauf lorsque vous essayez d'accéder à un lien d'objets:Python - Dictionnaire - Modifier __getitem__?

data["key"]["subkey"] 


def __getitem__(self, key, **args): 
    print key 
    ... 
    return self.dict[key] 

Lorsque En essayant d'accéder à une sous-clé qui n'existe pas, Python retourne simplement une KeyError sans imprimer "subkey", pourquoi est-ce et comment puis-je obtenir Python pour imprimer ce que j'essaie réellement d'obtenir?

Je sais que j'ai probablement mal compris la mécanique mais existe-t-il un moyen d'émuler un dictionnaire ET de suivre la chaîne de données demandée? Principalement si je peux dynamiquement enregistrer les variables manquantes dans un flux dictionnaire ...

Cela fonctionne évidemment (mais ce n'est pas la syntaxe native que je l'aime):

data["key:subkey"] 

def __getitem__(self, key, **args): 
    for slice in key.split(':'): 
     print key 
    ... 

Le but est d'imiter les éléments suivants ,

Travaux:

data = {'key' : {'subkey' : 1}} 
print data["key"]["subkey"] 

ne fonctionnera pas, mais je veux attirer l'exception dans __getitem__ puis créez la mi touche ssing automatiquement ou connectez-la sous-clé manquante:

data = {'key' : {}} 
print data["key"]["subkey"] 

Solution:

class Var(): 
    def __init__(self): 
     self.dict = {'test' : {}} 
    def __getitem__(self, var, **args): 
     print ':',var 
     if var in self.dict: 
      v = Var(self.dict[var]) 
      return v 

print vHandle['test']['down'] 

Sortie:

: Test

: vers le bas

Aucun

+0

Ai-je raté quelque chose ici, ou cela ne méritait-il pas un downvote du tout? Le downvoter pourrait-il s'expliquer? – Polynomial

+0

Quel est le type de 'data'? Quel est le type de 'data [" key "]'? Vous avez probablement besoin de montrer plus de code - sinon tout ce que nous pouvons faire est de deviner. (Non mon downvote) –

+2

Non, vous ne pouvez pas le faire directement (vous pouvez en retournant un objet enveloppé en faisant les mêmes signes). Pensez-y de cette façon: '_ = data ['key']' suivi de '_ ['subkey']'. Vous pourriez aussi avoir 'data ['key', 'subkey']' (touches de tuple) si c'était un moyen valide d'accéder aux données. –

Répondre

5

Le fait est que lorsque Python rencontre une expression telle que data["key"]["subkey"], ce qui est fait en interne est (data["key"])["subkey"]. C'est-à-dire que la première partie de l'expression est résolue: la récupération de l'élément "clé" de l'objet "données". Ensuite, Python essaie d'appeler __getitem__ sur l'objet résultant de cette expression. Si l'objet résultant n'a pas lui-même une méthode __getitem__, il y a votre erreur.

Il existe deux solutions de contournement possibles là: vous devez soit travailler avec « indices tuple » - comme data["key", "subkey"] (puis test sur votre méthode __getitem__ wether vous avez une instance de tuple comme la clé) - ou faire __getitem__ retour d'un objet spécialisé cela comporte également une méthode __getitem__ - même si tout ce qu'il fait est de se connecter les clés demandées.

+0

Ainsi, j'ai supposé que python appelait automatiquement __getitem__ à travers la même instance de variable après la première clé, je devine que je dois retourner une seconde instance de mon handle de variable pour que __getitem__ existe pour le second appel . Merci beaucoup! – Torxed

4

Rappelez-vous: tmp = foo['bar']['baz'] est le même que tmp = foo['bar']; tmp = tmp['baz']

Donc, pour permettre à des profondeurs arbitraires votre méthode __getitem__ doit retourner un nouvel objet qui contient également une telle méthode __getitem__.

+0

Je devine que je dois renvoyer une deuxième instance de mon handle variable depuis le "gestionnaire de variable" de sorte que __getitem__ existe également pour le second appel. Merci beaucoup! – Torxed

Questions connexes