I want to write a class that subclasses the Python list and notifies a certain other object when the list changes. Since there are many methods that need to be overridden, I opted for a solution like this, instead of overriding all methods that change the list:
destructiveMethods = ["__setitem__",
"__setslice__",
"__delitem__",
"__delslice__",
"append",
"extend",
"remove",
"reverse",
"sort"]
class OwnedList(list):
def __init__(self, owner, initValue=[]):
super(OwnedList, self).__init__(initValue)
def wrappedMethod(method):
def resultMethod(*args, **kwargs):
ret = method(*args, **kwargs)
self.owner.notify()
return ret
return resultMethod
self.owner = owner
for m in destructiveMethods:
setattr(self, m, wrappedMethod(getattr(self, m)))
This works for methods like “append” but not for special methods like “__setitem__”. For those, I simply get the old methods.
I’ve noticed that if I print the value of, say, append, I get something like:
<built-in method append of list object at 0x267a7a0>
But for __setitem__ (on a vanilla list) this is what I get:
<method-wrapper '__setitem__' of list object at 0x266fd40>
Maybe that has something to do with my problem.
Any help is appreciated. If you know a better way of accomplishing what I need to do, please share your ideas on that as well. Thanks.
UPDATE:
Something else I’ve noticed is calling __setitem__ directly on an OwnedList object works as expected, but using brackets does not.
Special methods can only defined on the object’s type and not on instancessource.
Compare
and
You should adapt
A, i.e. define your special methods directly in the class body and not in the constructor.