猴子修补python实例方法[重复]
Posted
技术标签:
【中文标题】猴子修补python实例方法[重复]【英文标题】:monkey-patching python an instance method [duplicate] 【发布时间】:2015-03-23 13:16:05 【问题描述】:我正在尝试对类实例进行猴子修补,但不太明白如何修补类方法没有问题。
>>> class Simple(object):
... def make(self, arg):
... return arg * 2
...
>>> s = Simple()
>>> def times_four(self, arg):
... return arg * 4
...
>>> Simple.make = times_four
>>> s.make(10)
40
但是假设我只想在实例中替换make
,那么最简单的方法是什么?
>>> def times_eight(self, arg):
... return arg * 8
>>> s.make = ???
【问题讨论】:
可能...我不太明白该代码中发生了什么。 我的问题是“嘲笑”还是“猴子补丁”? 你能解释一下区别吗? 从技术上讲,这些术语在某种程度上是同义词。不同之处在于意图 - 模拟通常是为了测试目的而进行猴子修补,而后者在其起源上更为普遍。 【参考方案1】:哇!
>>> import types
>>> s.make = types.MethodType(times_eight, s, Simple)
>>> s.make(10)
80
【讨论】:
【参考方案2】:方法仅在从类(而不是从实例字典)接收时自动传递 self
arg,因此您需要在那里传递一个 1-arg 函数:
s.make = lambda arg: times_eight(s, arg)
(您可以使用functools.partial
简化它。)
【讨论】:
我认为最好将对象添加到闭包lambda arg, s=s: time_eight(s, arg)
然而,这并不是真正的实例方法。正确的?这是一个 lambda 或部分,所以我不认为这真的有效。【参考方案3】:
您可以使用times_eight
的__get__
special method 创建一个新的实例方法:
>>> class Simple(object):
... def make(self, arg):
... return arg * 2
...
>>> s = Simple()
>>> def times_eight(self, arg):
... return arg * 8
...
>>> s.make = times_eight.__get__(s, Simple)
>>> s.make(10)
80
>>> type(s.make)
<type 'instancemethod'>
>>>
【讨论】:
您的解决方案也很有效。我只是在展示如何在不导入types.MethodType
的情况下做到这一点。 :)
在times_eight()
中使用super()
有效吗?以上是关于猴子修补python实例方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章