一些流行的博客网站通常在其URL中使用方括号,但ruby的内置URI.parse()方法会对它们产生阻碍,引发一个令人讨厌的异常,如:http://redmine.ruby-lang.org/issues/show/ 1466
我正在尝试编写一个简单的猴子补丁,它使用方括号优雅地处理URL.以下是我到目前为止的情况:
require 'uri'
module URI
def self.parse_with_safety(uri)
safe_uri = uri.replace('[', '%5B')
safe_uri = safe_uri.replace(']', '%5D')
URI.parse_without_safety(safe_uri)
end
alias_method_chain :parse, :safety
end
Run Code Online (Sandbox Code Playgroud)
但是在运行时会产生错误:
/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/module/aliasing.rb:33:in alias_method:NameError:模块'URI'的未定义方法'解析'
我怎样才能成功修补URI.parse?
我有几个不同种类的对象(不同的函数名称,不同的签名),我对它们进行修补,以便有一种从不同函数访问它们的通用方法.简而言之,有一个调度程序可以获取我想要修补的对象,并根据它调用不同修补程序的对象类型.修补程序将向对象添加方法:
def patcher_of_some_type(object):
def target(self, value):
# do something and call self methods
object.target = types.MethodType(target, object)
# many more of these
Run Code Online (Sandbox Code Playgroud)
随着程序变得越来越复杂,围绕对象(或对象类)的包装似乎更好.一些修补程序共享公共代码或相互关联.但我不控制对象创建,也不控制类创建.我只得到了这些物品.即使我能做到这一点,我只想包装(或修补)某些对象,而不是所有对象.
一种解决方案可能是为现有对象添加基类,但我不确定这是多么可维护和安全.还有其他解决方案吗?
如何修补猴子XMLHTTPRequest的onreadystatechange功能.我正在尝试添加一个函数,当从页面发出的每个ajax请求返回时,将调用该函数.
我知道这听起来像一个可怕的想法,但用例非常奇特.我想在控制台(jqconsole)中使用某个SDK,但在控制台内显示ajax调用的状态和结果,而不修改外部SDK.
我看过这篇文章有很多信息,但猴子修补回调似乎超出了我的JavaScript技能.
PS不能使用jQuery,因为它只支持从jQuery调用的jjj调用,而不是XMLHTTPRequests直接来自这里的情况.
我遇到像3.333333333那样的浮点数问题,我想把它变成3.33.我不想改变Serializer这类价值来自的所有类.有数千个序列化器,它们有多个字段,其值为3.333333333.
你能帮我找一下猴子补丁类型的解决方案,这样我就可以编写一个类或函数来转换浮点值.
我读到的关于猴子修补的一切都说要做这样的事情:
class String
def foo
#your special code
end
end
Run Code Online (Sandbox Code Playgroud)
但我找不到任何关于放置此代码的说明.在rails应用程序中,我可以把它放在我想要的任何疯狂的地方吗?在模块中?一个模型?
我是否需要在我定义monkeypatch的文件中包含一些内容?我是否需要在我想要使用它的地方包含我的monkeypatch?
我有一个自定义框架,它为不同的客户端运行不同的代码。我对某些方法进行了猴子修补,以便为客户定制功能。
这是简化的模式:
#import monkeypatches here
if self.config['client'] == 'cool_dudes':
from app.monkeypatches import Stuff
if self.config['client'] == 'cool_dudettes':
from app.monkeypatches import OtherStuff
Run Code Online (Sandbox Code Playgroud)
这是一个补丁示例:
from app.framework.stuff import Stuff
def function_override(self):
return pass
Stuff.function = function_override
Run Code Online (Sandbox Code Playgroud)
当程序以批处理方式执行时,这种方法效果很好,每次都从头开始旋转。然而,当运行单元测试时,我发现猴子补丁在测试中持续存在,导致意外的行为。
我意识到使用面向对象的继承方法来进行这些重写会好得多,但我继承了这个代码库,并且目前无权重新构建它到那种程度。
除非正确地重新构建程序,否则如何防止这些猴子补丁在单元测试中持续存在?
我正在使用 pytest 和 Monkeypatch 固定装置编写一些测试。按照规则,我导入类和方法以从它们正在使用的模块而不是源代码中模拟出来。
我正在为其编写测试的应用程序是一个使用标准环境的 Google App Engine 应用程序。因此我必须使用 python 2.7,我使用的实际版本是 2.7.15 - pytest 版本是 3.5.0
到目前为止,一切都运行良好,但在尝试模拟装饰器函数时遇到了问题。
从顶部开始。在一个名为decorators.py的py文件中包含所有auth装饰器,包括我想要模拟的装饰器。所讨论的装饰器是一个模块函数,而不是类的一部分。
def user_login_required(handler):
def is_authenticated(self, *args, **kwargs):
u = self.auth.get_user_by_session()
if u.access == '' or u.access is None:
# return the response
self.redirect('/admin', permanent=True)
else:
return handler(self, *args, **kwargs)
return is_authenticated
Run Code Online (Sandbox Code Playgroud)
该装饰器应用于Web请求功能。名为 handlers (handlers.UserDetails) 的文件夹中名为 UserDetails.py 的文件中的基本示例
from decorators import user_login_required
class UserDetailsHandler(BaseHandler):
@user_login_required
def get(self):
# Do web stuff, return html, etc
Run Code Online (Sandbox Code Playgroud)
在测试模块中,我设置测试如下:
from handlers.UserDetails import user_login_required
@pytest.mark.parametrize('params', get_params, ids=get_ids)
def …Run Code Online (Sandbox Code Playgroud) 我正在尝试对一些导入模块的 Python 3 代码进行单元测试。不幸的是,模块的编写方式,简单地导入它会产生令人不快的副作用,这对测试来说并不重要。我试图用unitest.mock.patch它来解决它,但运气不佳。
这是说明性示例的结构:
.
??? work
??? __init__.py
??? test_work.py
??? work.py
??? work_caller.py
Run Code Online (Sandbox Code Playgroud)
__init__.py 是一个空文件
.
??? work
??? __init__.py
??? test_work.py
??? work.py
??? work_caller.py
Run Code Online (Sandbox Code Playgroud)
import os
def work_on():
path = os.getcwd()
print(f"Working on {path}")
return path
def unpleasant_side_effect():
print("I am an unpleasant side effect of importing this module")
# Note that this is called simply by importing this file
unpleasant_side_effect()
Run Code Online (Sandbox Code Playgroud)
from work.work import work_on
class WorkCaller:
def call_work(self):
# Do …Run Code Online (Sandbox Code Playgroud) 在阅读了有关 Python 中猴子修补类的问题的答案后,我尝试将建议的解决方案应用于以下情况。
假设我们有一个模块a.py
class A(object):
def foo(self):
print(1)
class AA(A):
pass
Run Code Online (Sandbox Code Playgroud)
让我们尝试按如下方式对其进行猴子修补。当我们猴子补丁类时它起作用A:
>>> import a
>>> class B(object):
... def foo(self):
... print(3)
...
>>> a.A = B
>>> x = a.A()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)
但是如果我们尝试继承的类,它就不会被修补:
>>> y = a.AA()
>>> y.foo()
1
Run Code Online (Sandbox Code Playgroud)
有什么方法可以用所有继承的类来猴子修补该类吗?
编辑
目前,对我来说最好的解决方案如下:
>>> class AB(B, a.AA):
... pass
...
>>> a.AA = AB
>>> x = a.AA()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)
的任何复杂结构都将被继承,并且和a.AA之间的唯一区别是方法。这样,我们就不会修改任何内部类属性(如或)。唯一剩下的缺点是我们需要为每个继承的类执行此操作。ABa.AAfoo()__base____dict__
这是最好的方法吗?
fastai我试图了解使用's fastcore.basics.patch_toDecorator的附加值。方法如下fastcore:
from fastcore.basics import patch_to
class _T3(int):
pass
@patch_to(_T3)
def func1(self, a):
return self + a
Run Code Online (Sandbox Code Playgroud)
这是简单的猴子修补方法:
class simple_T3(int):
pass
def func1(self, a):
return self + a
simple_T3.func1 = func1
Run Code Online (Sandbox Code Playgroud)
检查这两个类没有发现任何差异。我知道简单的猴子修补可能会在更复杂的情况下导致问题,所以很高兴知道这些情况是什么?换句话说,它的附加值是多少fastcore.basics.patch_to?
monkeypatching ×10
python ×7
inheritance ×2
ruby ×2
unit-testing ×2
ajax ×1
django ×1
fast-ai ×1
javascript ×1
json ×1
metaclass ×1
pytest ×1
python-3.x ×1
uri ×1