问题
I've got a class which contains a number of lists where whenever something is added to one of the lists, I need to trigger a change to the instance's state. I've created a simple demonstration class below to try to demonstrate what I'm trying to do.
Suppose I have a class like this:
class MyClass:
added = False
def _decorator(self, f):
def func(item):
added = true
return f(item)
return func
def __init__(self):
self.list = [1, 2, 3]
self.list.append = self._decorator(self.list.append)
Since a list is built in, I cannot change it's .append method
cls = MyClass() #gives me an AttributeError since '.append' is readonly
Ideally, I could do the following:
cls = MyClass()
cls.list.append(4)
cls.added #would be true
How should I go about this? Would subclassing list
allow me to change it's behavior in this way? If so, how would I pass in the class's state without changing the methods signature?
Thanks!
回答1:
You cannot monkey-patch builtins, so subclassing is the only way (and actually better and cleaner IMHO). I'd go for something like this:
class CustomList(list):
def __init__(self, parent_instance, *args, **kwargs):
super(CustomList, self).__init__(*args, **kwargs)
self.parent_instance = parent_instance
def append(self, item):
self.parent_instance.added = True
super(CustomList, self).append(item)
class MyClass(object):
added = False
def __init__(self):
self.list = CustomList(self, [1,2,3])
c = MyClass()
print c.added # False
c.list.append(4)
print c.added # True
回答2:
Would this suit your needs?
class MyClass(object):
added = False
def __init__(self):
self.list = [1,2,3]
def append(self, obj):
self.added = True
self.list.append(obj)
cls = MyClass()
cls.append(4)
cls.added #true
It might be helpful to know what exactly you're trying to achieve.
来源:https://stackoverflow.com/questions/24396528/add-a-decorator-to-existing-builtin-class-method-in-python