标签: monkeypatching

你可以在Python中的核心类型上修补补丁方法吗?

Ruby可以向Number类和其他核心类型添加方法以获得如下效果:

1.should_equal(1)
Run Code Online (Sandbox Code Playgroud)

但似乎Python无法做到这一点.这是真的?如果是这样,为什么?是否与类型无法修改的事实有关?

更新:我不想谈论猴子修补的不同定义,而是只关注上面的例子.我已经得出结论,由于你们中的一些人已经回答,所以无法做到.但我想更详细地解释为什么不能这样做,也许如果Python中有什么功能可以允许这样做.

回答你们中的一些人:我可能想要这样做的原因只是美学/可读性.

 item.price.should_equal(19.99)
Run Code Online (Sandbox Code Playgroud)

这更像是英语,并清楚地表明哪个是测试值,哪个是预期值,如下所示:

should_equal(item.price, 19.99)
Run Code Online (Sandbox Code Playgroud)

这个概念就是Rspec和其他一些Ruby框架所基于的.

ruby python programming-languages fluent-interface monkeypatching

49
推荐指数
6
解决办法
2万
查看次数

在Rails中,如何向String类添加新方法?

我想在我的Rails项目中为不同的对象构建一个索引,并希望添加一个'count_occurences'方法,我可以在String对象上调用它.

我看到我可以做类似的事情

class String
  def self.count_occurences
    do_something_here
  end
end
Run Code Online (Sandbox Code Playgroud)

定义此方法的确切方法是什么,以及将代码放在我的Rails项目中的位置?

谢谢

ruby monkeypatching ruby-on-rails-3

48
推荐指数
3
解决办法
3万
查看次数

你可以修补*只是一个带闭包的嵌套函数,还是必须重复整个外部函数?

我们使用的第三方库包含一个相当长的函数,它在其中使用嵌套函数.我们对该库的使用触发了该函数中的错误,我们非常希望解决该错误.

不幸的是,库维护者修复有点慢,但我们不想分叉库.在修复问题之前,我们也无法保留我们的版本.

我们更喜欢使用猴子修补来修复此问题,因为这比修补源更容易跟踪.然而,要重复一个非常大的功能,只需更换内部功能就足够了,并且让其他人更难看到我们究竟改变了什么.我们是否坚持使用图库蛋的静态补丁?

内部函数依赖于关闭变量; 一个人为的例子是:

def outerfunction(*args):
    def innerfunction(val):
        return someformat.format(val)

    someformat = 'Foo: {}'
    for arg in args:
        yield innerfunction(arg)
Run Code Online (Sandbox Code Playgroud)

在哪里我们想要只替换它的实现innerfunction().实际的外部功能远远更长.当然,我们会重用关闭的变量并维护函数签名.

python closures monkeypatching

48
推荐指数
2
解决办法
3426
查看次数

Monkey-patch Python类

我有一个班级,位于一个单独的模块中,我无法改变.

from module import MyClass

class ReplaceClass(object)
  ...

MyClass = ReplaceClass
Run Code Online (Sandbox Code Playgroud)

除了这个文件之外,这不会改变MyClass.但是,如果我要添加这样的方法

def bar():
   print 123

MyClass.foo = bar
Run Code Online (Sandbox Code Playgroud)

这将工作,foo方法将在其他地方可用.

如何完全替换课程?

python monkeypatching

45
推荐指数
3
解决办法
3万
查看次数

猴子修补@property

是否有可能修补@property我无法控制的类实例的值?

class Foo:
    @property
    def bar(self):
        return here().be['dragons']

f = Foo()
print(f.bar)  # baz
f.bar = 42    # MAGIC!
print(f.bar)  # 42
Run Code Online (Sandbox Code Playgroud)

显然,上述尝试分配时会产生错误f.bar.有# MAGIC!可能吗?这个实现细节@property是一个黑盒子,而不是间接的猴子可修补.需要替换整个方法调用.它只需要影响单个实例(如果不可避免,类级别修补就可以,但改变后的行为必须只选择性地影响给定的实例,而不是该类的所有实例).

python monkeypatching python-3.x

38
推荐指数
3
解决办法
4343
查看次数

在groovy中向对象动态添加属性或方法

是否可以在Groovy中动态地向对象添加属性或方法?这是我到目前为止所尝试的:

class Greet {
  def name
  Greet(who) { name = who[0].toUpperCase() + [1..-1] }
  def salute() { println "Hello $name!" }
}

g = new Greet('world')  // create object
g.salute()              // Output "Hello World!"

g.bye = { println "Goodbye, $name" }
g.bye()
Run Code Online (Sandbox Code Playgroud)

但我得到以下异常:

Hello World!
Caught: groovy.lang.MissingPropertyException: No such property: bye for class: Greet
Possible solutions: name
    at test.run(greet.groovy:11)
Run Code Online (Sandbox Code Playgroud)

groovy monkeypatching

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

如何在Python中的单元测试场景中模拟HTTP请求

我想为我所有与HTTP相关的测试都包含一个Web服务器.它不需要非常复杂.我宁愿不依赖在线.所以我可以测试一下我的程序的一些选项.

  1. 启动服务器
  2. 使用适当的mime类型,响应代码等创建一些资源(URI).
  3. 运行测试(最好不要为每个测试启动服务器)
  4. 关闭服务器.

有关此代码的任何提示都会有所帮助.我用BaseHTTPServer尝试了一些但尚未成功的东西.nosetests命令似乎无限期地等待.

import unittest
from foo import core

class HttpRequests(unittest.TestCase):
    """Tests for HTTP"""

    def setUp(self):
        "Starting a Web server"
        self.port = 8080
        # Here we need to start the server
        #
        # Then define a couple of URIs and their HTTP headers
        # so we can test the code.
        pass

    def testRequestStyle(self):
        "Check if we receive a text/css content-type"
        myreq = core.httpCheck()
        myuri = 'http://127.0.0.1/style/foo'
        myua = "Foobar/1.1"
        self.asserEqual(myreq.mimetype(myuri, myua), "text/css")

    def testRequestLocation(self):
        "another test" 
        pass …
Run Code Online (Sandbox Code Playgroud)

python unit-testing monkeypatching http mocking

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

如何在python中乘以函数?

def sub3(n):
    return n - 3

def square(n):
    return n * n
Run Code Online (Sandbox Code Playgroud)

在python中组合函数很容易:

>>> my_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [square(sub3(n)) for n in my_list]
[9, 4, 1, 0, 1, 4, 9, 16, 25, 36]
Run Code Online (Sandbox Code Playgroud)

不幸的是,当想要使用合成作为关键时,它有点蹩脚:

>>> sorted(my_list, key=lambda n: square(sub3(n)))
[3, 2, 4, 1, 5, 0, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

这真的应该是sorted(my_list, key=square*sub3),因为heck,函数__mul__不用于其他任何事情:

>>> square * sub3
TypeError: unsupported operand type(s) for *: 'function' and 'function'
Run Code Online (Sandbox Code Playgroud)

好吧,让我们来定义吧!

>>> …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching function function-composition

31
推荐指数
1
解决办法
1762
查看次数

在python中扩展内置类

如何在python中扩展内置类?我想在str类中添加一个方法.
我已经做了一些搜索,但我发现的都是较旧的帖子,我希望有人知道更新的东西.

python string monkeypatching

29
推荐指数
3
解决办法
2万
查看次数

猴子修补ruby中的类的推荐方法

我注意到有两种常见的方法来修补ruby中的类:

在类上定义新成员,如下所示:

class Array
   def new_method
     #do stuff
   end
end
Run Code Online (Sandbox Code Playgroud)

并在类对象上调用class_eval:

Array.class_eval do
   def new_method
      #do stuff
   end
end
Run Code Online (Sandbox Code Playgroud)

我想知道两者之间是否存在任何差异,使用一种方法是否优于另一种方法?

ruby monkeypatching

27
推荐指数
2
解决办法
8640
查看次数