Setting custom methods with setattr ()

Is it possible to dynamically assign special methods, such as __getitem__ , to an instance of a class using setattr() ? For example, if I have this:

 class Example (object): pass 

And then try the following:

 >>> 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 great:

 >>> example.__getitem__('something') 1 

Obviously, something is happening here that I don’t understand how Python performs method searches for this kind of thing. Should these methods be installed in the class and not on the instance?

UPDATE

So, I have to clearly clarify how I know that I see this in the Example class ... I was hoping there was a way to set them for each instance, but the consensus that I see so far, you cannot do this.

+6
source share
2 answers

The problem here is that __getitem__() is defined at the class level, not at the 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 
+6
source

Have you tried monkeypatching class, not instance?

 >>> example = Example() >>> setattr(Example, '__getitem__', lambda self,x: 1) 
0
source

Source: https://habr.com/ru/post/915097/


All Articles