On Nov 15, 12:01 pm, Jon Clements <jon...@googlemail.com> wrote: > On Nov 15, 7:23 pm, Steve Howell <showel...@yahoo.com> wrote: > > > On Nov 15, 10:25 am, Steve Howell <showel...@yahoo.com> wrote: > > > > [see original post...] > > > I am most > > > interested in the specific mechanism for changing the __getitem__ > > > method for a subclass on a dictionary. Thanks in advance! > > > Sorry for replying to myself, but I just realized that the last > > statement in my original post was a little imprecise. > > > I am more precisely looking for a way to change the behavior of foo > > ['bar'] (side effects and possibly return value) where "foo" is an > > instance of a class that subclasses "dict," and where "foo" is not > > created by me. The original post gives more context and example code > > that does not work as I expect/desire. > > [quote fromhttp://docs.python.org/reference/datamodel.html] > For instance, if a class defines a method named __getitem__(), and x > is an instance of this class, then x[i] is roughly equivalent to > x.__getitem__(i) for old-style classes and type(x).__getitem__(x, i) > for new-style classes. > [/quote] >
Ok, thanks to Jon and Gary pointing me in the right direction, I think I can provide an elaborate answer my own question now. Given an already instantiated instance foo of Foo where Foo subclasses dict, you cannot change the general behavior of calls of the form foo [bar]. (Obviously you can change the behavior for specific examples of bar after instantiation by setting foo['apple'] and foo['banana'] as needed, but that's not what I mean.) This may be surprising to naive programmers like myself, given that is possible to change the behavior of foo.bar() after instantiation by simply saying "foo.bar = some_method". Also, with old-style classes, you can change the behavior of foo[bar] by setting foo.__getitem__. Even in new-style classes, you can change the behavior of foo.__getitem__(bar) by saying foo.__getitem__ = some_method, but it is a pointless exercise, since foo.__getitem__ will have no bearing on the processing of "foo[bar]." Finally, you can define __getitem__ on the Foo class itself to change how foo[bar] gets resolved, presumably even after instantiation of foo itself (but this does not allow for instance-specific behavior). Here is the difference: foo.value looks for a definition of value on the instance before looking in the class hierarchy foo[bar] can find __getitem__ on foo before looking at Foo and its superclasses, if Foo is old-style foo[bar] will only look for __getitem__ in the class hierarchy if Foo derives from a new-style class Does anybody have any links that points to the rationale for ignoring instance definitions of __getitem__ when new-style classes are involved? I assume it has something to do with performance or protecting us from our own mistakes? So now I am still in search of a way to hook into calls to foo[bar] after foo has been instantiated. It is all test code, so I am not particularly concerned about safety or future compatibility. I can do something really gross like monkeypatch Foo class instead of foo instance and keep track of the ids to decide when to override behavior, but there must be a simpler way to do this. -- http://mail.python.org/mailman/listinfo/python-list