标签: monkeypatching

猴子修补与部分功能

我正在尝试SomeClass从导入的包中对一个方法进行monkeypatch :

from somepackage import SomeClass

def newmethod(obj, node, **kwargs):
    """ """

SomeClass.oldmethod = newmethod
Run Code Online (Sandbox Code Playgroud)

在哪里objnode在默认调用签名SomeClass.oldmethod:

class SomeClass(object):

    def oldmethod(obj, node):
        """ """  
Run Code Online (Sandbox Code Playgroud)

我知道monkeypatching不是一个好习惯,但我们需要一个解决方法,同时我们解决了一些无法解决的问题.上面的方法很有效,但是我们想用部分函数来做这件事.例如:

from functools import partial
newmethod_a = partial(newmethod, foo='a')
newmethod_b = partial(newmethod, foo='b')
Run Code Online (Sandbox Code Playgroud)

调用部分函数是因为我们需要传递不同的**kwargs.但是当我现在尝试超载时:

SomeClass.oldmethod = newmethod_a
Run Code Online (Sandbox Code Playgroud)

我得到一个与传递的参数数量相关的错误,但它非常特定于我的问题所以粘贴它可能没有帮助...我认为错误与oldmethod采取两个位置参数(obj, node)和我的部分的调用签名有关功能不传递到一基准objnode正确.我尝试了不同的结构,如:

newmethod_a = partial(SomeClass.newmethod, foo='a')
Run Code Online (Sandbox Code Playgroud)

对不起,我无法生成一个最小的工作示例.我希望也许专家会从经验中认识到这个问题,并告诉我,如果我在尝试的范围内甚至是可能的partial.

谢谢

python monkeypatching partials

11
推荐指数
1
解决办法
583
查看次数

使用ctypes检索本机基类的地址

我希望能够将证书传递给Python的ssl库,而无需临时文件.似乎Python的ssl模块不能这样做.

要解决此问题,我想从本机模块中检索SSL_CTX存储在ssl._ssl._SSLContext类中的基础结构_ssl.使用ctypes然后我可以SSL_CTX_*使用该上下文从libssl 手动调用相应的函数.这里显示如何在C中执行此操作,我将通过ctypes执行相同的操作.

不幸的是,我陷入了我设法挂钩load_verify_locations函数的地步,ssl._ssl._SSLContext但似乎无法获得ssl._ssl._SSLContext结构实例的正确内存地址.load_verify_locations看到的所有函数都是父ssl.SSLContext对象.

我的问题是,如何从ssl.SSLContext对象的实例到本机基类的内存ssl._ssl._SSLContext?如果我愿意,我可以轻松访问其ctx成员.

到目前为止,这是我的代码.关于如何将本机Python模块进行monkeypatch的信用转到Lincoln Clarete的禁果项目

Py_ssize_t = hasattr(ctypes.pythonapi, 'Py_InitModule4_64') and ctypes.c_int64 or ctypes.c_int

class PyObject(ctypes.Structure):
    pass

PyObject._fields_ = [
    ('ob_refcnt', Py_ssize_t),
    ('ob_type', ctypes.POINTER(PyObject)),
]

class SlotsProxy(PyObject):
    _fields_ = [('dict', ctypes.POINTER(PyObject))]

class PySSLContext(ctypes.Structure):
    pass

PySSLContext._fields_ = [
        ('ob_refcnt', Py_ssize_t),
        ('ob_type', ctypes.POINTER(PySSLContext)),
        ('ctx', ctypes.c_void_p),
        ]

name = …
Run Code Online (Sandbox Code Playgroud)

ctypes monkeypatching cpython pyopenssl python-3.x

11
推荐指数
1
解决办法
327
查看次数

是否可以在Python实例级别覆盖__getitem__?

使用以下代码:

import types

class Foo():
    def __getitem__(self, x):
        return x

def new_get(self, x):
    return x + 1

x = Foo()
x.__getitem__ = types.MethodType(new_get, x)
Run Code Online (Sandbox Code Playgroud)

x.__getitem__(42)将返回43,但x[42]将返回42。

有没有一种方法可以__getitem__在Python实例级别进行覆盖?

python monkeypatching

11
推荐指数
2
解决办法
222
查看次数

如何使用 pytest Monkeypatch 来修补类

我想使用 [pytest Monkeypatch][1] 来模拟导入到单独模块中的类。这实际上可能吗?如果可能的话,如何做到这一点?我似乎还没有看到这种具体情况的例子。假设您有一个应用程序并在 Something.py 中导入了 A 类

from something import A #Class is imported

class B :
  def __init__(self) :
   self.instance = A() #class instance is created

  def f(self, value) :
    return self.instance.g(value)
Run Code Online (Sandbox Code Playgroud)

在我的 test.py 中我想在 B 中模拟 A

from something import B

#this is where I would mock A such that
def mock_A :
  def g(self, value) :
    return 2*value

#Then I would call B
c = B()
print(c.g(2)) #would be 4

I see how monkeypatch can be …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching class pytest

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

猴子补丁还是不补?

这是更普遍的问题,然后是语言特定的,虽然我在使用python ncurses模块时碰到了这个问题.我需要显示区域设置字符并将它们识别为字符,所以我很快就从curses模块中修补了一些函数/方法.

这就是我称之为快速而丑陋的解决方案,即使它有效.而且变化相对较小,所以我希望我没有搞砸任何东西.我的计划是找到另一个解决方案,但看到它的工作和运作良好,你知道它是怎么回事,我继续处理我必须处理的其他问题,我敢肯定,如果没有这个问题,我将永远不会让它更好.

然而,更普遍的问题出现在我面前 - 显然有些语言允许我们在类中修补大块代码.如果这是我自己只使用的代码,或者变化很小,那就没关系.如果其他开发人员接受我的代码会怎样,他看到我使用了一些众所周知的模块,所以他可以认为它可以像以前一样工作.然后,这种方法突然表现得与之不同.

所以,非常主观,我们应该使用猴子补丁,如果是,何时以及如何?我们该怎么记录它?


编辑:for @guerda:

Monkey-patching是在执行时动态地改变某些代码片段的行为的能力,而不需要改变代码本身.

Python中的一个小例子:

import os
def ld(name):
    print("The directory won't be listed here, it's a feature!")

os.listdir = ld

# now what happens if we call os.listdir("/home/")?
os.listdir("/home/")
Run Code Online (Sandbox Code Playgroud)

language-agnostic oop monkeypatching

10
推荐指数
1
解决办法
2036
查看次数

我可以替换或修改jQuery UI小部件上的函数吗?怎么样?(猴子补丁)

如果我想调整jQuery UI对象的一些功能,通过替换其中一个函数,我将如何去做呢?

示例:假设我想修改jQuery自动完成小部件呈现建议的方式.自动完成对象上有一个方法如下所示:

_renderItem: function( ul, item) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.label + "</a>" )
        .appendTo( ul );
},
Run Code Online (Sandbox Code Playgroud)

我可以替换它吗?

我想这可能叫做Monkey Patching.

怎么样?我会用什么语法?

jquery monkeypatching

10
推荐指数
1
解决办法
5090
查看次数

猴子补丁__del__到新功能

出于特定的调试目的,我想包装任意对象的del函数来执行额外的任务,比如将对象的最后一个值写入文件.

理想情况下,我想编写monkey(x),它应该意味着删除x时会打印x的最终值

现在我认为del是一个类方法.所以以下是一个开始:

class Test:
    def __str__(self):
        return "Test"

def p(self):
    print(str(self))

def monkey(x):
    x.__class__.__del__=p

a=Test()
monkey(a)
del a
Run Code Online (Sandbox Code Playgroud)

但是,如果我想要特定的对象,我想我需要动态地将它们的类重写为一个新的?此外我还需要这样做,因为我无法访问内置类型的del

谁知道如何实现?

python monkeypatching

10
推荐指数
1
解决办法
1037
查看次数

如何修补对象的构造函数?

我想修补这个'Controller'对象的构造函数.但是我如何修补构造函数,所以我仍然可以调用原始函数?这就是我尝试过的.

// original
function Controller() {
    this._tag = 'div';
}
Controller.prototype.tag = function() {
    console.log(this._tag);
}

var c = new Controller(); 
c.tag(); // -> 'div', as expected


// patch attempt
var original = Controller;
Controller = function() {
    original.apply(this);
    this._tag = 'patched'; // patch
}

var c = new Controller();
c.tag(); // no method tag, prototype appears wiped...
Run Code Online (Sandbox Code Playgroud)

javascript monkeypatching

10
推荐指数
1
解决办法
3438
查看次数

如何在猴子修补时调用原始方法?

我在主项目中有一堂课,我不想改变.

class A():
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    def name(self):
        # this method could be much more complex
        return self.lastname.upper()
Run Code Online (Sandbox Code Playgroud)

我正在尝试构建一个插件mechansim.到目前为止,我有一个像这样的扩展点:

if __name__ == '__main__':
    ''' The main project has an extension point that allows me to do'''
    # for each class extension such as AExtended:
    A.name = AExtended.name
    ''' After the extensions are loaded, some behaviours may be changed'''
    a = A("John", "Doe")
    print(a.name())
Run Code Online (Sandbox Code Playgroud)

插件可以这样写:

class AExtended(A):
    ''' This is an extension I provide …
Run Code Online (Sandbox Code Playgroud)

python oop overriding monkeypatching python-3.x

10
推荐指数
2
解决办法
3674
查看次数

是否可以在Java中进行猴子修补,如果没有替代方案?

这是8年前在这里被问到的,从那时起已经过了8年.我想再次问这个问题,看看是否有人开发了一个猴子修补的框架,工具或库.

基本上我需要它是一个java应用程序,我应用自己的补丁.由于这个项目由另一个团队维护,我希望能够保留/应用我制作的任何补丁,以及他们制作的补丁.

java monkeypatching

10
推荐指数
2
解决办法
3332
查看次数