using __getitem()__ correctly

Charles T. Smith cts.private.yahoo at gmail.com
Wed Dec 30 09:40:28 EST 2015


On 2015年12月31日 00:11:24 +1100, Chris Angelico wrote:
> On Wed, Dec 30, 2015 at 11:57 PM, Charles T. Smith
> <cts.private.yahoo at 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


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /