如果我猴子修补一个模块:
# mokeypatch.py
import other_module
def replacement(*args, **kwargs):
pass
other_module.some_func = replacement
Run Code Online (Sandbox Code Playgroud)
这会影响直接导入的模块some_func,还是取决于导入的顺序?如果第三个模块是这样的:
# third_module.py
from other_module import some_func
Run Code Online (Sandbox Code Playgroud)
首先,运行此代码,然后运行我们的猴子补丁。会third_module.some_func是旧的吗?
我正在开发一个 ruby 项目,我们计划使用 ruby 字符串进行一些操作。有些操作很简单(例如计算单词数),而其他操作则更复杂(例如检查给定字符串是否采用正确的语言)。
实现此目的的一种可能方法是使用String额外的方法修补类,而不修改任何现有方法"some string".word_count,并添加和 等行为"some string".cjk?。
另一种方法FileUtils是创建一个充满方法的类或模块,并始终使用字符串作为参数,例如OddClassName.word_count("some string")和OddClassName.cjk?("some string")。由于可读性,我们更喜欢第一个。
我知道猴子修补第一个替代方案中描述的基本类可能会发生名称冲突。但是,如果这是主应用程序,而不是库,我应该担心它吗?
所以,问题是:
请提出任何替代方案。
我正在尝试在第三方 gem 中修改控制器类。准确地说,我正在尝试添加参数包装来设计控制器。在initializers/wrap_parameters.rb我添加了以下位:
Rails.application.config.after_initialize do
DeviseController.class_eval do
wrap_parameters :user, format: [:json]
end
end
Run Code Online (Sandbox Code Playgroud)
当应用程序启动时它工作得很好,但是当我修改我的一个控制器类时,参数包装立即停止工作。好像控制器类是在没有上述补丁的情况下重新加载的。
如何让我的猴子补丁持久化?
谢谢
我想覆盖Promise构造函数和Promise中的then方法。因此,每当有人创建一个新的Promise对象时,首先将执行我的代码,然后将调用原始的promise构造函数。
同样,当有人调用Promise的.then函数时,首先将执行我的代码,然后将执行该then函数的回调。
我试过了
var bind = Function.bind;
var unbind = bind.bind(bind);
function instantiate(constructor, args) {
return new (unbind(constructor, null).apply(null, args));
}
var oldProto = Promise.prototype;
Promise = function() {
console.log("Promise instantiated");
var promise = instantiate(Promise, arguments);
return promise;
};
Promise.prototype = oldProto;
Run Code Online (Sandbox Code Playgroud)
当使用
var myFirstPromise = new Promise((resolve, reject) => {
setTimeout(function(){
resolve("Success!"); // Yay! Everything went well!
}, 250);
});
myFirstPromise.then((successMessage) => {
console.log("Yay! " + successMessage);
});
Run Code Online (Sandbox Code Playgroud)
它导致无限循环,控制台充满了Promise instantiated日志。我还尝试了以下方法:
Promise = function(Promise) {
MyPromise.prototype …Run Code Online (Sandbox Code Playgroud) 我试图实现的总体目标是将 Keras 模型发送给每个 Spark 工作器,以便我可以在应用于 DataFrame 列的 UDF 中使用该模型。为此,Keras 模型需要是可腌制的。
似乎很多人通过猴子修补 Model 类来成功腌制 keras 模型,如下面的链接所示:
http://zachmoshe.com/2017/04/03/pickling-keras-models.html
但是,我还没有看到任何关于如何与 Spark 一起执行此操作的示例。我的第一次尝试只是make_keras_picklable()在驱动程序中运行该函数,这允许我在驱动程序中腌制和取消腌制模型,但我无法在 UDF 中腌制模型。
def make_keras_picklable():
"Source: https://zachmoshe.com/2017/04/03/pickling-keras-models.html"
...
make_keras_picklable()
model = Sequential() # etc etc
def score(case):
....
score = model.predict(case)
...
def scoreUDF = udf(score, ArrayType(FloatType()))
Run Code Online (Sandbox Code Playgroud)
我得到的错误表明在 UDF 中解压模型没有使用猴子修补的模型类。
AttributeError: 'Sequential' object has no attribute '_built'
Run Code Online (Sandbox Code Playgroud)
看起来另一个用户在这篇 SO 帖子中遇到了类似的错误,答案是“make_keras_picklable()也在每个工作人员上运行”。没有给出如何做到这一点的例子。
我的问题是:召集make_keras_picklable()所有工人的适当方式是什么?
我尝试使用broadcast()(见下文)但得到了与上面相同的错误。
def make_keras_picklable():
"Source: https://zachmoshe.com/2017/04/03/pickling-keras-models.html"
...
make_keras_picklable()
spark.sparkContext.broadcast(make_keras_picklable())
model = Sequential() …Run Code Online (Sandbox Code Playgroud) 我正在尝试测试模块:
包/模块.py
DATA_PATH = os.path.join(os.path.dirname(__file__), "data")
class SomeClass:
def __init__(self):
self.filename = os.path.join(DATA_PATH, "ABC.txt")
Run Code Online (Sandbox Code Playgroud)
在tests/module_test.py中我正在尝试做
from package import module
@patch("package.module.DATA_PATH", "data_path_here") # doesn't work
class TestSomeClass(unittest.TestCase):
def setUp(self):
module.DATA_PATH = "data_path_here" # doesn't work
self.obj= SomeClass()
@patch("package.module.DATA_PATH", "data_path_here") # doesn't work either
def test_constructor(self):
self.assertEqual(r"data_path_here\ABC.txt", self.obj.filename)
Run Code Online (Sandbox Code Playgroud)
但是 DATA_PATH 仍然没有被模拟出来。我想我尝试了所有可能的选项来模拟它,但它仍然返回原始路径而不是“data_path_here”
我究竟做错了什么?
编辑:它不是在 Python 单元测试框架中修改全局变量的副本, 因为该解决方案不起作用
我想测试一个函数的默认行为。我有以下几点:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar(text=DEFAULT_VALUE):
print(text)
Run Code Online (Sandbox Code Playgroud)
# test/test_app.py
import app
def test_app(monkeypatch):
monkeypatch.setattr('app.foo.DEFAULT_VALUE', 'patched')
app.foo.bar()
assert 0
Run Code Online (Sandbox Code Playgroud)
输出是hello; 不是我想要的。
一种解决方案是显式传递默认值: app.foo.bar(text=app.foo.DEFAULT_VALUE)。
但我觉得有趣的是,当默认为全局范围时,这似乎不是问题:
# app/foo.py
DEFAULT_VALUE = 'hello'
def bar():
print(DEFAULT_VALUE)
Run Code Online (Sandbox Code Playgroud)
输出是 patched。
为什么会发生这种情况?还有比显式传递默认值更好的解决方案吗?
我有一个使用 MonkeyPatch 来测试某些功能的测试库。我想向这个库添加一个测试来测试对我的端点的请求调用 functionB()。
我使用 Mock() 库来创建模拟函数,然后我使用 MonkeyPatch.setattr() 传递它。但是,模拟函数永远不会被调用并且断言总是失败。我究竟做错了什么?
mock_function_B = Mock()
monkeypatch.setattr(file, 'function_B', mock_function_B)
params = json.dumps({'foo': "bar"})
res = client.post('/some_endpoint', headers=content_type_json, data=params)
assert res.status_code == 201
assert mock_function_B.call_count == 1
Run Code Online (Sandbox Code Playgroud)
我希望 call_count 为 1,因为我知道 some_endpoint 调用 function_B(并且从日志中,我看到它已被调用)但是,断言失败,因为 call_count 为 0。
我有一个 JS 文件,猴子将一些功能修补到 3rd 方包上:
import L from 'leaflet';
import 'leaflet.pm';
import 'leaflet-textpath';
...
// do monkeypatching with all 3 packages.
// Only leaflet and leaflet.pm have typedef packages.
...
export default L;
Run Code Online (Sandbox Code Playgroud)
L(传单)有一个@types包含所有类型的包。
export as namespace L;
...
// export all type defs
...
Run Code Online (Sandbox Code Playgroud)
此时我不想将monkeypatch JS文件转换为TS。我可以处理没有对monkeypatched 功能进行类型检查的情况。
鉴于此,我试图将其monkeypatch.js作为L命名空间导入,以便我至少可以将它与L类型一起使用。
我尝试了以下各种方法,但没有任何运气:
import MonkeyPatch from 'monkey-patch';
const TS = MonkeyPatch as L;
Run Code Online (Sandbox Code Playgroud)
由于无法将命名空间L用作类型,因此这不起作用。
如何将monkeypatch JS 文件作为L命名空间导入以便进行类型检查L?
javascript monkeypatching leaflet typescript typescript-typings
考虑以下:
class MockResponse:
status_code = 200
@staticmethod
def json():
return {'key': 'value'}
# where api_session is a fixture
def test_api_session_get(monkeypatch, api_session) -> None:
def mock_get(*args, **kwargs):
return MockResponse()
monkeypatch.setattr(requests.Session, 'get', mock_get)
response = api_session.get('endpoint/') # My wrapper around requests.Session
assert response.status_code == 200
assert response.json() == {'key': 'value'}
monkeypatch.assert_called_with(
'endpoint/',
headers={
'user-agent': 'blah',
},
)
Run Code Online (Sandbox Code Playgroud)
我如何断言get我正在修补的被调用'/endpoint'和headers?当我现在运行测试时,我收到以下失败消息:
FAILED test/utility/test_api_session.py::test_api_session_get - AttributeError: 'MonkeyPatch' object has no attribute 'assert_called_with'
我在这里做错了什么?感谢所有提前回复的人。
monkeypatching ×10
python ×4
mocking ×3
pytest ×3
javascript ×2
ruby ×2
apache-spark ×1
devise ×1
import ×1
keras ×1
leaflet ×1
namespaces ×1
overriding ×1
pickle ×1
promise ×1
prototype ×1
pyspark ×1
python-3.x ×1
typescript ×1
unit-testing ×1