假设我有一个Python类,我想添加一个额外的属性.
两者之间有什么区别吗?
import path.MyClass
MyClass.foo = bar
Run Code Online (Sandbox Code Playgroud)
并使用类似的东西:
import path.MyClass
setattr(MyClass, 'foo', bar)
Run Code Online (Sandbox Code Playgroud)
?
如果没有,为什么人们似乎做第二个而不是第一个?(例如http://concisionandconcinnity.blogspot.com/2008/10/chaining-monkey-patches-in-python.html)
让我们使用一个真实世界的例子.
我想修补一下WillPaginate :: LinkRenderer.to_html方法.
到目前为止,我尝试过:
Ë
module Monkeys::WillPaginateNohtml
def to_html
debugger
super
end
end
WillPaginate::LinkRenderer.send(:include, Monkeys::WillPaginateNohtml)
Run Code Online (Sandbox Code Playgroud)
但不知何故,调试器无法通过.看起来修补失败了.
任何帮助将不胜感激,谢谢!
我想知道是否有可能确保我所制作的类中的方法不会被猴子修补(Monkey patch).麋能实现吗?
考虑以下:
{
package Foo;
sub hello{print "HI"}
1;
}
package main;
sub Foo::hello {print "bye"}
Foo::hello()#bye
Run Code Online (Sandbox Code Playgroud) 我正在尝试从 devtool 扩展中为 React 的渲染方法创建一个猴子补丁,因为我正在尝试为我的扩展中的一个功能重新创建类似于 react_devtool 的 api 的东西。我用这两行代码欺骗了被检查窗口的虚拟 DOM
var reactRoot = document.querySelector("[data-reactroot]")
var dom = reactRoot[Object.getOwnPropertyNames(reactRoot)[0]]
Run Code Online (Sandbox Code Playgroud)
我还听说通过访问窗口的__REACT_DEVTOOLS_GLOBAL_HOOK__. 我需要能够在页面更新时从 React 的 internalInstance 访问一组新数据(setState/rerender)。
这是我对 React 的渲染方法进行猴子修补的尝试。此代码从通过 my 注入的单独文件运行,该文件content-scripts.js能够在检查的窗口中访问 React 应用程序的 dom。
const reactInstances = window.__REACT_DEVTOOLS_GLOBAL_HOOK__._renderers
const instance = reactInstances[Object.keys(reactInstances)[0]]
console.log('current windows React INSTANCE: ', instance)
var reactRender = instance.Mount.render
console.log('reacts render method: ', reactRender)
reactRender = (function (original) {
return function (nextElement, container, callback) {
var result = original.apply(this, arguments)
console.log(original, result)
return result
} …Run Code Online (Sandbox Code Playgroud) javascript monkeypatching content-script reactjs react-devtools
考虑我的模块 "mymodule.py"
# contents of "mymodule.py"
def func1(x):
return x * 2
Run Code Online (Sandbox Code Playgroud)
我想模拟这个函数并改变它的返回值。根据文档,我可以这样做:
# contents of "test_mymodule.py"
import mymodule
import pytest
@pytest.fixture
def mock_func1():
def mock_ret(*args, **kwargs):
return 2
def test_func1_a(monkeypatch, mock_func1):
monkeypatch.setattr(mymodule, "func1", mock_func1)
assert mymodule.func1(1) == 2
def test_func1_b(monkeypatch, mock_func1):
monkeypatch.setattr(mymodule, "func1", mock_func1)
assert mymodule.func1(1) != 37
Run Code Online (Sandbox Code Playgroud)
但是,我不想为每个测试修补模块。monkeypatch.setattr对整个测试模块的范围进行一次的正确方法是什么test_mymodule.py?
我期待这样的事情
# contents of "test_mymodule.py"
import mymodule
import pytest
@pytest.fixture
def mock_func1():
def mock_ret(*args, **kwargs):
return 2
monkeypatch.setattr(mymodule, "func1", mock_func1)
def test_func1_a():
assert mymodule.func1(1) == 2 …Run Code Online (Sandbox Code Playgroud) 如果我的库中有一个contrib附加程序,其中包含依赖项(例如requests),我希望用户必须安装该附加程序才能访问 CLI API,但我在 CI 测试期间安装了 contrib 附加程序,我如何使用pytest来MonkeyPatch删除测试期间的依赖关系以确保我的检测正确?
例如,如果contrib额外的内容会另外安装requests,那么我希望用户必须这样做
$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)
然后能够在命令行上使用 CLI API,如下所示
$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)
wheremyfunction使用requests依赖项
$ python -m pip install mylib[contrib]
Run Code Online (Sandbox Code Playgroud)
我如何在测试中模拟或猴子补丁 ,以便我可以确保用户正确地收到警告以及如果他们这样做requestspytestModuleNotFoundError
$ python -m pip install mylib
$ mylib contrib myfunction
Run Code Online (Sandbox Code Playgroud)
?在阅读了有关 pytest 标签的其他一些问题后,我仍然认为我不明白如何做到这一点,所以我在这里问。
今天我遇到了一种情况,我需要进行扩展以对网页中的某些对象进行猴子修补。
然而,我几乎没有找到关于如何实际实现它的文档,我尝试使用该userScriptsAPI(目前仅适用于 Firefox),但该对象与页面的 HTML DOM 上的window上下文隔离。window
我知道这是可能的,因为像 GreaseMonkey 这样的用户脚本管理器实现了一个unsafeWindow对象,该对象使脚本可以直接访问网页的非隔离上下文中的对象,从而使猴子修补变得非常容易。
所以我想知道这是如何实现的。我试图研究名为ViolentMonkey的用户脚本管理器的源代码,我发现它定义unsafeWindow为src/injected/web/gm-api-wrapper.js:53对global对象的引用,但我无法找到它在源代码中定义的位置。
我知道这不是通过简单地<script>在页面中注入一个元素来实现的,因为根据我的检查,页面的 DOM 中没有可见的元素。
我对这个很酷的机制的实现很好奇,我很确定我错过了一些明显的东西,所以我需要你的帮助来摘掉我的眼罩!
javascript monkeypatching google-chrome-extension tampermonkey firefox-addon-webextensions
我知道,我知道,这很脏.我想知道是否可以劫持__init__Python模块的模块来替换它自己的模块.
我问这是因为我需要阻止django lib启动它的初始进程的某些部分,使其崩溃我们的配置.
是的,最好修复django lib并发回补丁.是的,我和作者有联系.但就目前而言,我需要快速修复.
我试图找出猴子修补的工作原理以及我如何使它适用于我自己的对象/方法.
我一直在看这个lib,它确实是我想做的事情:https: //github.com/antecedent/patchwork
有了它,您可以从对象重新定义方法.它使用'猴子补丁'技术.但是我无法通过查看源代码来确定究竟发生了什么.
所以假设我有以下对象:
//file: MyClass.php
namespace MyClass;
class MyClass {
public function say()
{
echo 'Hi';
}
}
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情:
Monkeypatch\replace('MyClass', 'say', function() {
echo 'Hello';
});
$obj = new MyClass();
$obj->say(); // Prints: 'Hello'
Run Code Online (Sandbox Code Playgroud)
但我不知道如何编码实际的修补部分.我知道在这种情况下命名空间很重要.但是,这究竟是如何让我修补某种方法呢?我是否需要在某处使用eval()(如果是这样,如何)?
我无法找到关于此事的任何好例子,除了:http: //till.klampaeckel.de/blog/archives/105-Monkey-patching-in-PHP.html
但我真的不知道如何将它应用于我自己的对象/方法.我希望有一个很好的解释或例子.
我正在研究一个内部的Ruby DSL并让它看起来尽可能漂亮,我需要修补Symbol类并添加一些运算符.我想对我如何做到这一点负责,并希望将补丁的范围和生命周期限制在特定的代码块中.这样做有标准模式吗?这里有一些伪代码来展示我的想法:
class SomeContext
def self.monkey_patch_region(&block)
context = SomeContext.new
context.monkey_patch_Symbol
context.instance_eval(&block)
context.unmonkey_patch_Symbol
end
# magical method
def monkey_patch_Symbol
#...
end
# another magical method
def unmonkey_patch_Symbol
#...
end
Run Code Online (Sandbox Code Playgroud)
结束
monkeypatching ×10
python ×4
javascript ×2
pytest ×2
class ×1
django ×1
dsl ×1
final ×1
firefox-addon-webextensions ×1
init ×1
moose ×1
perl ×1
php ×1
pytest-mock ×1
reactjs ×1
ruby ×1
tampermonkey ×1