标签: monkeypatching

我如何在python中进行monkeypatching?

我不得不在python中进行一些内省,它并不漂亮:

name = sys._getframe(1).f_code
name = "%s:%d %s()" %(os.path.split(name.co_filename)[1],name.co_firstlineno,name.co_name)
Run Code Online (Sandbox Code Playgroud)

得到类似的东西

foo.py:22 bar() blah blah
Run Code Online (Sandbox Code Playgroud)

在我们的调试输出中.

理想情况下,我希望通过这种信息向stderr添加任何内容 - 是否有可能在python中全局更改print的行为?

python monkeypatching

8
推荐指数
1
解决办法
508
查看次数

python3:使用.__ get __()将类方法绑定到类实例,但是为什么呢?

我知道如果你想为一个类实例添加一个方法,你不能像这样做一个简单的赋值:

>>> def print_var(self): # method to be added
        print(self.var)
>>> class MyClass:
        var = 5
>>> c = MyClass()
>>> c.print_var = print_var
Run Code Online (Sandbox Code Playgroud)

这确实会导致print_var行为像正常的函数,所以self参数不具有他的典型含义:

>>> c.print_var
<function print_var at 0x98e86ec>
>>> c.print_var()
Traceback (most recent call last):
  File "<pyshell#149>", line 1, in <module>
    c.print_var()
TypeError: print_var() takes exactly 1 argument (0 given)
Run Code Online (Sandbox Code Playgroud)

为了让函数被认为是一个方法(即将它绑定到实例),我曾经使用过这段代码:

>>> import types
>>> c.print_var = types.MethodType(print_var, c)
>>> c.print_var
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>>
>>> c.print_var()
5
Run Code Online (Sandbox Code Playgroud)

但我发现它 …

python methods monkeypatching descriptor python-3.x

8
推荐指数
1
解决办法
2533
查看次数

是否可以重写Javascript数组或对象以进行调用?

我想弄清楚Array []和Object []是否可以被Array()和Object()取代.函数原型可以插入到数组或对象原型链中以使它们可调用.基本上我正在寻找这样的事情:

// some magic with prototypes
????????????????

a = [1, 3, 4]
b = [1, 3, 4]

console.log(a[1]) // prints 3
console.log(b(1)) // prints 3

a[0] = -1
// same as
b(0, -1)

console.log(a[1], b(1)) // prints -1 -1
Run Code Online (Sandbox Code Playgroud)

非常感谢!

javascript arrays monkeypatching

8
推荐指数
1
解决办法
1208
查看次数

在Ruby中修补类/方法的猴子

我正在尝试对我用Ruby编写的一段代码进行单元测试File.open.为了模仿它,我monkeypatched File.open到以下:

class File
  def self.open(name, &block)
    if name.include?("retval")
      return "0\n"
    else
      return "1\n"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

问题是我使用rcov来运行整个事情,因为它使用File.open来编写代码覆盖率信息,它获得monkeypatched版本而不是真实版本.我如何取消monkeypatch这种方法将其恢复为原始方法?我试过搞乱alias,但到目前为止无济于事.

ruby testing monkeypatching rcov

8
推荐指数
1
解决办法
3276
查看次数

Python 3:猴子修补的代码不能通过多处理重新导入

简单来说

当模块A的函数应该是可导入的时候,如何从模块B中获取补丁模块A,以便我可以使用multiprocessing标准库包运行模块A的函数?

背景

客户端请求了一个不适用于我们任何其他客户端的修补程序,因此我创建了一个新分支,并为它们编写了一个单独的模块,以便从主分支中轻松合并更改.为了保持客户端与预修复程序行为的向后兼容性,我在应用程序中将此修补程序实现为可配置设置.因此,我不想替换旧代码 - 只需在打开设置时对其进行修补即可.我通过猴子修补做到了这一点.

代码结构

__main__模块读入配置文件.如果配置打开了修补程序的开关,则通过用模块中定义的代码替换几个函数来__main__修补我enginehotfix模块 - 实质上,被替换的函数是最大化函数关键函数.该engine模块稍后会加载一个工作池multiprocessing.

问题

一旦multiprocessing工作人员开始工作,第一件事multiprocessing就是重新导入*engine模块并查找__main__试图替换的关键功能(然后multiprocessing将控制交给我的代码并开始最大化算法).由于engine正在通过一个全新的流程重新导入,并且新流程不会重新运行__main__(配置文件被读取的地方)因为这会导致无限循环,所以它不知道重新进行猴子补丁engine.

问题

如何在代码中保持模块化(即,将修补程序代码保存在单独的模块中)并仍然利用Python的multiprocessing包?

*注意我的代码必须在Windows(对我的客户端)和Unix(为了我的理智......)上工作

python import monkeypatching multiprocessing python-3.x

8
推荐指数
1
解决办法
437
查看次数

"在线"猴子修补功能

你的程序暂停了pdb.set_trace().

有没有办法修补当前正在运行的功能,并"恢复"执行?

这可能通过调用框架操作吗?


一些背景:

通常情况下,我会有一个处理大量数据的复杂函数,而不具备我将找到的数据类型的先验知识:

def process_a_lot(data_stream):
    #process a lot of stuff
    #...
    data_unit= data_stream.next()
    if not can_process(data_unit)
        import pdb; pdb.set_trace()
    #continue processing
Run Code Online (Sandbox Code Playgroud)

这种方便的构造在遇到未知数据时启动交互式调试器,因此我可以随意检查它并更改process_a_lot代码以正确处理它.

这里的问题是,当data_stream你很大的时候,你真的不想再次咀嚼所有的数据(我们假设next它很慢,所以你不能保存已有的数据并在下一次运行时跳过)

当然,您可以在调试器中随意替换其他函数.您也可以替换函数本身,但不会更改当前的执行上下文.

编辑: 既然有些人越来越扯到:我知道有很多的结构化代码的方式,使得您的处理功能是分开process_a_lot.我并没有真正询问如何构建代码的方法,以及如何从代码未准备好处理替换的情况中恢复(在运行时).

python monkeypatching function

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

覆盖__init__.py中的len - python

我想__init__.py通过以下方式为我的包的文件中的另一个函数分配另一个函数:

llen = len
len = lambda x: llen(x) - 1
Run Code Online (Sandbox Code Playgroud)

它工作正常,但只在__init__.py文件中.如何让它影响我的包中的其他模块?

python monkeypatching built-in shadowing

8
推荐指数
1
解决办法
239
查看次数

如何导入pytest monkeypatch插件?

我想使用pytest monkeypatch插件,但我无法弄清楚如何导入它.我试过了:

  • import monkeypath
  • import pytest.monkeypatch
  • from pytest import monkeypatch

python monkeypatching pytest

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

如何修补`__call__`方法?

我似乎无法修补__call__类实例的方法(是的,我想修补单个实例,而不是所有实例).

以下代码:

class A(object):
    def test(self):
        return "TEST"

    def __call__(self):
        return "EXAMPLE"

a = A()
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))
a.__call__ = lambda : "example"
a.test = lambda : "test"
print("call method: {0}".format(a.__call__))
print("test method: {0}".format(a.test))

print(a())
print("Explicit call: {0}".format(a.__call__()))
print(a.test())
Run Code Online (Sandbox Code Playgroud)

输出:

call method: <bound method A.__call__ of <__main__.A object at 0x7f3f2d60b6a0>>
test method: <bound method A.test of <__main__.A object at 0x7f3f2d60b6a0>>
call method: <function <lambda> at 0x7f3f2ef4ef28>
test method: <function <lambda> at 0x7f3f2d5f8f28>
EXAMPLE
Explicit call: …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching

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

Django Rest Framework Json数据猴子修补

我遇到像3.333333333那样的浮点数问题,我想把它变成3.33.我不想改变Serializer这类价值来自的所有类.有数千个序列化器,它们有多个字段,其值为3.333333333.

你能帮我找一下猴子补丁类型的解决方案,这样我就可以编写一个类或函数来转换浮点值.

python django json monkeypatching django-rest-framework

7
推荐指数
1
解决办法
512
查看次数