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
我想在我的Rails项目中为不同的对象构建一个索引,并希望添加一个'count_occurences'方法,我可以在String对象上调用它.
我看到我可以做类似的事情
class String
def self.count_occurences
do_something_here
end
end
Run Code Online (Sandbox Code Playgroud)
定义此方法的确切方法是什么,以及将代码放在我的Rails项目中的位置?
谢谢
我们使用的第三方库包含一个相当长的函数,它在其中使用嵌套函数.我们对该库的使用触发了该函数中的错误,我们非常希望解决该错误.
不幸的是,库维护者修复有点慢,但我们不想分叉库.在修复问题之前,我们也无法保留我们的版本.
我们更喜欢使用猴子修补来修复此问题,因为这比修补源更容易跟踪.然而,要重复一个非常大的功能,只需更换内部功能就足够了,并且让其他人更难看到我们究竟改变了什么.我们是否坚持使用图库蛋的静态补丁?
内部函数依赖于关闭变量; 一个人为的例子是:
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().实际的外部功能远远更长.当然,我们会重用关闭的变量并维护函数签名.
我有一个班级,位于一个单独的模块中,我无法改变.
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方法将在其他地方可用.
如何完全替换课程?
是否有可能修补@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是一个黑盒子,而不是间接的猴子可修补.需要替换整个方法调用.它只需要影响单个实例(如果不可避免,类级别修补就可以,但改变后的行为必须只选择性地影响给定的实例,而不是该类的所有实例).
是否可以在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) 我想为我所有与HTTP相关的测试都包含一个Web服务器.它不需要非常复杂.我宁愿不依赖在线.所以我可以测试一下我的程序的一些选项.
有关此代码的任何提示都会有所帮助.我用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) 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中扩展内置类?我想在str类中添加一个方法.
我已经做了一些搜索,但我发现的都是较旧的帖子,我希望有人知道更新的东西.
我注意到有两种常见的方法来修补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)
我想知道两者之间是否存在任何差异,使用一种方法是否优于另一种方法?
monkeypatching ×10
python ×7
ruby ×3
closures ×1
function ×1
groovy ×1
http ×1
mocking ×1
python-3.x ×1
string ×1
unit-testing ×1