On Thu, 31 Dec 2015 00:11:24 +1100, Chris Angelico wrote: > On Wed, Dec 30, 2015 at 11:57 PM, Charles T. Smith > <cts.private.ya...@gmail.com> wrote: >> Hello, >> >> I thought __getitem__() was invoked when an object is postfixed with an >> expression in brackets: >> >> - abc[n] >> >> and __getattr__() was invoked when an object is postfixed with an dot: >> >> - abc.member > > That would be normal (with the caveat that __getattr__ is called only if > the attribute isn't found; __getattribute__ is called unconditionally). > >> but my __getitem__ is being invoked at this time, where there's no >> subscript (going into a spiral recursion death): >> >> self.mcc = self.attrs.mcc >> >> Can anybody explain to me why __getitem__() would be invoked here? > > Can you post your entire class, or at least __getattr__? Also check > superclasses, if there are any. > > ChrisA
(PDB)isinstance (self.attrs, attrdict) True As is so often the case, in composing my answer to your question, I discovered a number of problems in my class (e.g. I was calling __getitem__() myself!), but I'm puzzled now how to proceed. I thought the way you avoid triggering __getattr__() from within that was to use self.__dict__[name] but that doesn't work: (PDB)p self.attrs.keys() ['mcc', 'abc'] (PDB)p self.attrs.__dict__['abc'] *** KeyError: KeyError('abc',) class attrdict(dict): def __init__ (self, name = None): if name: self.update (name) print "attrdict: instantiated: ", name # AutoVivification def __getattr__ (self, name): print "attrdict:av:__getattr__: entered for ", name #, " in ", self #if not name in self.__dict__.keys(): if not name in self.keys(): print "attrdict:av:__getattr__: autovivifying ", name #self.__dict__.__setitem__ (name, self.__class__()) #self.__setitem__ (name, self.__class__()) self.__setattr__ (name, self.__class__()) #return self.__getitem__(name) #return self.__dict__.__getitem__(name) return self.__getattribute__ (name) def __getitem__ (self, key): print "attrdict:av:__getitem__: entered for ", key #, " in ", self return self.__getitem__(key) def __getattr__deprecated (self, name): return self[name] def __setattr__(self, name, value): self[name] = value -- https://mail.python.org/mailman/listinfo/python-list