Setting special methods using setattr()

introspection, python, setattr

Solution

The issue here is that `__getitem__()` is defined at a class-level, not at instance-level:

>>> class Example (object):
...     pass
... 
>>> example = Example()
>>> setattr(Example, '__getitem__', lambda x, y: 1)
>>> example['something']
1

If you need it to be instance-specific:

>>> class Example(object):
...     def __getitem__(self, item):
...         return self._getitem(item)
... 
>>> example = Example()
>>> setattr(example, '_getitem', lambda x: 1)
>>> example['something']
1
>>> example2 = Example()
>>> setattr(example2, '_getitem', lambda x: 2)
>>> example['something']
1
>>> example2['something']
2

Problem

Is it possible to dynamically assign special methods, such as `__getitem__`, to a class instance using `setattr()`? For example, if I have this: ``` class Example (object): pass ``` And then try this: ``` >>> example = Example() >>> setattr(example, '__getitem__', lambda x: 1) ``` I get this: ``` >>> example['something'] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Example' object has no attribute '__getitem__' ``` But of course this works just fine: ``` >>> example.__getitem__('something') 1 ``` There's obviously something going on here that I don't understand regarding how Python does method lookups for this sort of thing. Do these methods have to be set on the class, rather than on the instance? UPDATE: So, I should make it clear than I know I can see this on the `Example` class...I was hoping there was a way to set them per-instance, but the consensus I'm seeing so far is You Can't Do That.

Original source