标签: monkeypatching

将方法添加到现有对象实例

我已经读过可以在Python中向现有对象(即,不在类定义中)添加方法.

我知道这样做并不总是好事.但是人们怎么可能这样做呢?

python oop methods monkeypatching

596
推荐指数
13
解决办法
22万
查看次数

什么是猴子补丁?

我想了解什么是猴子补丁或猴子补丁?

这类似于方法/运算符重载或委托吗?

这些东西有什么共同之处吗?

python monkeypatching terminology

496
推荐指数
8
解决办法
17万
查看次数

当猴子修补方法时,你能从新实现调用重写方法吗?

假设我是猴子修补类中的方法,我怎么能从覆盖方法调用重写方法?就像有点像super

例如

class Foo
  def bar()
    "Hello"
  end
end 

class Foo
  def bar()
    super() + " World"
  end
end

>> Foo.new.bar == "Hello World"
Run Code Online (Sandbox Code Playgroud)

ruby monkeypatching

422
推荐指数
2
解决办法
8万
查看次数

如何动态地向类添加属性?

目标是创建一个类似于db结果集的模拟类.

因此,例如,如果数据库查询使用dict表达式返回{'ab':100, 'cd':200},那么我想看到:

>>> dummy.ab
100
Run Code Online (Sandbox Code Playgroud)

起初我想也许我可以这样做:

ks = ['ab', 'cd']
vs = [12, 34]
class C(dict):
    def __init__(self, ks, vs):
        for i, k in enumerate(ks):
            self[k] = vs[i]
            setattr(self, k, property(lambda x: vs[i], self.fn_readyonly))

    def fn_readonly(self, v)
        raise "It is ready only"

if __name__ == "__main__":
    c = C(ks, vs)
    print c.ab
Run Code Online (Sandbox Code Playgroud)

但是c.ab返回一个属性对象.

更换setattr线路k = property(lambda x: vs[i])完全没用.

那么在运行时创建实例属性的正确方法是什么?

PS我知道如何__getattribute__使用该方法?

python monkeypatching runtime properties

193
推荐指数
11
解决办法
19万
查看次数

一个猴子如何在python中修补一个函数?

我在使用另一个功能从另一个模块替换功能时遇到了麻烦,这让我发疯了.

假设我有一个模块bar.py,如下所示:

from a_package.baz import do_something_expensive

def a_function():
    print do_something_expensive()
Run Code Online (Sandbox Code Playgroud)

我有另一个模块,看起来像这样:

from bar import a_function
a_function()

from a_package.baz import do_something_expensive
do_something_expensive = lambda: 'Something really cheap.'
a_function()

import a_package.baz
a_package.baz.do_something_expensive = lambda: 'Something really cheap.'
a_function()
Run Code Online (Sandbox Code Playgroud)

我希望得到结果:

Something expensive!
Something really cheap.
Something really cheap.
Run Code Online (Sandbox Code Playgroud)

但相反,我得到了这个:

Something expensive!
Something expensive!
Something expensive!
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

python monkeypatching

76
推荐指数
3
解决办法
4万
查看次数

我可以在包装函数之前修补Python装饰器吗?

我有一个装饰器的功能,我正在尝试借助Python Mock库进行测试.我想使用mock.patch将模拟'旁路'装饰器替换为真正的装饰器,它只调用该函数.我无法弄清楚的是如何在真正的装饰器包装函数之前应用补丁.我已经在补丁目标上尝试了一些不同的变体,并重新排序补丁和导入语句,但没有成功.有任何想法吗?

python unit-testing monkeypatching mocking decorator

66
推荐指数
3
解决办法
3万
查看次数

"猴子补丁"在Ruby中究竟意味着什么?

据维基百科称,猴子补丁是:

一种在不改变原始源代码的情况下扩展或修改动态语言的运行时代码的方法.

来自同一条目的以下陈述使我感到困惑:

在Ruby中,术语monkey patch被误解为对类的任何动态修改,并且通常用作在运行时动态修改任何类的同义词.

我想知道Ruby修补猴子的确切含义.它是在做类似下面的事情,还是其他什么?

class String
  def foo
    "foo"
  end
end
Run Code Online (Sandbox Code Playgroud)

ruby monkeypatching terminology

62
推荐指数
3
解决办法
3万
查看次数

我可以为内置Python类型添加自定义方法/属性吗?

例如 - 假设我想helloWorld()为Python的dict类型添加一个方法.我可以这样做吗?

JavaScript有一个行为方式的原型对象.也许这是糟糕的设计,我应该继承dict对象,但它只适用于子类,我希望它可以在任何和所有未来的字典上工作.

以下是它在JavaScript中的表现:

String.prototype.hello = function() {
    alert("Hello, " + this + "!");
}
"Jed".hello() //alerts "Hello, Jed!"
Run Code Online (Sandbox Code Playgroud)

这是一个有用的链接,包含更多示例 - http://www.javascriptkit.com/javatutors/proto3.shtml

python monkeypatching custom-attributes built-in-types

62
推荐指数
4
解决办法
2万
查看次数

猴子在Python中修补另一个模块中的一个类

我正在使用其他人编写的模块.我想修补__init__模块中定义的类的方法.我发现如何执行此操作的示例都假设我自己会调用该类(例如,Monkey-patch Python类).然而,这种情况并非如此.在我的情况下,该类在另一个模块中的函数内被初始化.请参阅下面的(大大简化)示例:

thirdpartymodule_a.py

class SomeClass(object):
    def __init__(self):
        self.a = 42
    def show(self):
        print self.a
Run Code Online (Sandbox Code Playgroud)

thirdpartymodule_b.py

import thirdpartymodule_a
def dosomething():
    sc = thirdpartymodule_a.SomeClass()
    sc.show()
Run Code Online (Sandbox Code Playgroud)

mymodule.py

import thirdpartymodule_b
thirdpartymodule.dosomething()
Run Code Online (Sandbox Code Playgroud)

有没有办法修改__init__方法,SomeClass以便dosomething从mymodule.py调用它时,例如,打印43而不是42?理想情况下,我能够包装现有方法.

我无法更改thirdpartymodule*.py文件,因为其他脚本依赖于现有功能.我宁愿不必创建我自己的模块副本,因为我需要做的改变非常简单.

编辑2013-10-24

我忽略了上面例子中的一个小而重要的细节.SomeClass是这样导入的thirdpartymodule_b:from thirdpartymodule_a import SomeClass.

要做FJ建议的补丁我需要替换副本thirdpartymodule_b,而不是thirdpartymodule_a.例如thirdpartymodule_b.SomeClass.__init__ = new_init.

python unit-testing monkeypatching class

61
推荐指数
3
解决办法
4万
查看次数

使用常规编码器使对象JSON可序列化

JSON序列化自定义非可序列化对象的常规方法是子类化json.JSONEncoder,然后将自定义编码器传递给转储.

它通常看起来像这样:

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, foo):
            return obj.to_json()

        return json.JSONEncoder.default(self, obj)

print json.dumps(obj, cls = CustomEncoder)
Run Code Online (Sandbox Code Playgroud)

我正在尝试做的是使用默认编码器进行序列化.我环顾四周但找不到任何东西.我的想法是编码器会看到一些字段来确定json编码.类似的东西__str__.也许是一个__json__领域.在python中有这样的东西吗?

我想制作一个模块的类,我正在使用JSON序列化给使用该软件包的每个人,而不必担心实现他们自己的[普通]自定义编码器.

python serialization json monkeypatching

59
推荐指数
3
解决办法
6万
查看次数