如何扩展Python对象的方法?
我有一个垃圾邮件对象列表:如何扩展Python对象的方法?,python,methods,Python,Methods,我有一个垃圾邮件对象列表: class Spam: def update(self): print('updating spam!') 其中一些可能是SpamLite对象: class SpamLite(Spam): def update(self): print('this spam is lite!') Spam.update(self) 我希望能够从列表中获取任意对象,并向其更新方法中添加一些内容,例如: def pois
class Spam:
def update(self):
print('updating spam!')
其中一些可能是SpamLite对象:
class SpamLite(Spam):
def update(self):
print('this spam is lite!')
Spam.update(self)
我希望能够从列表中获取任意对象,并向其更新方法中添加一些内容,例如:
def poison(spam):
tmp = spam.update
def newUpdate(self):
print 'this spam has been poisoned!'
tmp(self)
spam.update = newUpdate
我希望spam.update()现在可以打印:
this spam has been poisoned!
updating spam!
或
这取决于它是垃圾邮件还是仅仅是垃圾邮件
但这不起作用,因为spam.update()不会自动传入self参数,而且因为如果tmp离开作用域或进行更改,它就不会调用旧的更新。我有办法做到这一点吗
def poison(spam):
tmp = spam.update
def newUpdate():
print 'this spam has been poisoned!'
tmp()
spam.update = newUpdate
完整脚本:
输出:
更新垃圾邮件!
这个垃圾邮件是lite!
更新垃圾邮件!
*******************************************************************************
此垃圾邮件已中毒!
更新垃圾邮件!
此垃圾邮件已中毒!
这个垃圾邮件是lite!
更新垃圾邮件!
另一种方法是:
在python世界中,MonkeyPatching是不受欢迎的 您应该真正使用Mixin方法并使用多重继承
然后,您可以动态地替换(更新)父级以达到所需的效果。使用如下装饰器:
def method_decorator(f):
def wrapper(self, *args, **kwargs):
print('this spam has been poisoned!')
return f(self)
return wrapper
class Spam:
def update(self):
print('updating spam!')
@method_decorator
def update2(self):
print('updating spam!')
Spam().update()
Spam().update2()
这张照片是:
updating spam!
this spam has been poisoned!
updating spam!
如果您想了解更多关于装饰师的信息,请阅读以下内容:
以上不是一个“好公民”的装潢者,读了这篇文章就知道怎么写了。请确保同时检查装饰程序库:
HTH多态性?应该很容易实现,但我从来没有写过python。顺便说一句,这通俗地说就是“猴子补丁”。使用
super
而不是调用Spam.update
,这被认为是一种很好的做法。这如何允许一个人在特定实例上而不是其他实例上更改方法?你是说要更改它的\uuuuuu class\uuuuuu
属性吗?@themissinglint:是的。在这种情况下,self
被称为spam
。您不需要显式地传递它;只要在需要时在newUpdate()
中使用它即可。如果您想更改Spam
类的所有实例的update
方法(不仅仅是所选的几个),那么您可以:Spam.update=types.UnboundMethodType(lambda self:…对self做点什么…,None,Spam)
;看见
updating spam!
this spam is lite!
updating spam!
*******************************************************************************
this spam has been poisoned!
updating spam!
this spam has been poisoned!
this spam is lite!
updating spam!
class Spam:
def update(self):
print('updating spam!')
class SpamLite(Spam):
def update(self):
print('this spam is lite!')
Spam.update(self)
def poison(spam):
import types
tmp = spam.update
def newUpdate(self):
print 'this spam has been poisoned!'
tmp()
newUpdate = types.MethodType(newUpdate, spam, Spam)
spam.update = newUpdate
spam = Spam()
spam_lite = SpamLite()
poison(spam)
poison(spam_lite)
spam.update()
print
spam_lite.update()
def method_decorator(f):
def wrapper(self, *args, **kwargs):
print('this spam has been poisoned!')
return f(self)
return wrapper
class Spam:
def update(self):
print('updating spam!')
@method_decorator
def update2(self):
print('updating spam!')
Spam().update()
Spam().update2()
updating spam!
this spam has been poisoned!
updating spam!