2009-12-01 7 views
0

Comment est-ce implémenté au niveau de python? J'ai un objet qui prétend être dicté pour la plupart (en rétrospective j'aurais dû juste sous-classer dict, mais je préfèrerais ne pas refactoriser la base de code, et j'aimerais aussi le savoir pour référence future), qui ressemble à quelque chose un peu commedans le protocole en ce qui concerne la séquence

class configThinger(object): 
    _config = {} 
    def __getitem__(self, key): 
     return self._config[key] 
    def __setitem__(self, key, value): 
     self._config[key] = value 

qui fonctionne exactement comme il est censé et se comporte correctement lorsque je tente d'accéder à ses éléments comme configThingerInstance [ « tout »]

Mais un appel comme

t = configThinger() 
t.populate() # Internal method that fills it with some useful data 
if 'DEBUG' in t: 
    doStuff() 

provoque une erreur KeyError étant donné que le protocole "in" effectue probablement une recherche getitem() pour la clé en question. Dois-je soulever une autre exception pour dire que ce n'est pas là? Je préfère ne pas faire quelque chose comme ça.

try: 
    t['DEBUG'] 
except KeyError: 
    pass 
else: 
    doStuff() 

En outre, où dans la documentation est-ce?

Je regardais autour

http://docs.python.org/tutorial/datastructures.html

http://docs.python.org/library/stdtypes.html

mais en essayant tragiquement à Google pour quelque chose de spécifique au mot 'dans' est une folie :(

EDIT 1:

Avec une pile d'empreintes de trace, je peux voir que le programme appelle configThingerInstance getitem (0)

cependant

t = {'rawk': 1, 
    'rawr': 2, 
    } 
t[0] # Raises KeyError 
'thing' in t # returns False 
+0

@Richo, ce que vous observez est une tentative désespérée de dernier recours pour des types qui ne définissent ni __contain__ ni __iter__ (ils essaient de voir si, juste peut-être, ce sont des iterables qui ont peur de prononcer ce nom; -). –

+0

J'avais une intuition qui était ce qu'elle était, ce qui était le point où j'ai commencé à chercher des docs, puis à demander ici, plutôt que de tâtonner pour essayer de trouver un oeuf de Pâques que Guido a laissé;) – richo

Répondre

1

Pour le meilleur support pour l'opérateur in (vérification adhésion alias de confinement), mettre en œuvre la méthode spéciale __contains__ de votre classe configThinger:

class configThinger(object): 
    _config = {} 
    def __getitem__(self, key): 
     return self._config[key] 
    def __setitem__(self, key, value): 
     self._config[key] = value 
    def __contains__(self, key): 
     return key in self._config 

les documents sont here (expliquant également d'autres manières moins importantes de prendre en charge l'opérateur in).