I ran the following program, and found its output surprising in one place: class OnlyAl: def __getitem__(self, key): return 'al'
class OnlyBob(dict): def __getitem__(self, key): return 'bob' import sys; print sys.version al = OnlyAl() bob = OnlyBob() print al['whatever'] al.__getitem__ = lambda key: 'NEW AND IMPROVED AL!' print al['whatever'] print bob['whatever'] bob.__getitem__ = lambda key: 'a NEW AND IMPROVED BOB seems impossible' print bob['whatever'] 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] al NEW AND IMPROVED AL! bob bob In attempting to change the behavior for bob's dictionary lookup, I am clearly doing something wrong, or maybe even impossible. Obviously the examples are contrived, but I am interested on a purely academic level why setting __getitem__ on bob does not seem to change the behavior of bob['foo']. Note that OnlyBob subclasses dict; OnlyAl does not. On a more practical level, I will explain what I am trying to do. Basically, I am trying to create some code that allows me to spy on arbitrary objects in a test environment. I want to write a spy() method that takes an arbitrary object and overrides its implementation of __getitem__ and friends so that I can see how library code is invoking the object (with print statements or whatever). Furthermore, I want spy() to recursively spy on objects that get produced from my original object. The particular use case is that I am creating a context for Django templates, and I want to see which objects are getting rendered, all the way down the tree. It would be pretty easy to just create a subclass of the context method to spy at the top level, but I want to recursively spy on all its children, and that is why I need a monkeypatching approach. The original version had spy recursively returning proxy/masquerade objects that intercepted __getitem__ calls, but it becomes brittle when the proxy objects go off into places like template filters, where I am not prepared to intercept all calls to the object, and where in some cases it is impossible to gain control. Although I am interested in comments on the general problems (spying on objects, or spying on Django template rendering), I am most interested in the specific mechanism for changing the __getitem__ method for a subclass on a dictionary. Thanks in advance! -- http://mail.python.org/mailman/listinfo/python-list