在 Python 中,术语monkey patch
仅指在运行时动态修改类或模块,作为初学者,我很难在 python 上下文中理解这个术语。有人能用一个现实世界的例子向我解释一下我们到底是怎么做的吗?
- 类的动态修改
- 运行时动态修改模块
我坚持用一个现实世界的例子(尽可能简单)来理解在哪些场景下我们必须执行这样的任务?
猴子修补是一种进行全局底层更改的方法,现有代码将继续运行,但行为会发生变化。
改变内置行为的一个非常非常简单的例子str
命令:
b.py
def foo(msg):
s = str(msg)
print s, type(s)
a.py
import b
b.foo('foo')
# monkey-patch
import __builtin__
__builtin__.str = unicode
b.foo('foo')
# Results:
#foo <type 'str'>
#foo <type 'unicode'>
The a
模块使用以下命令修改了其他代码的行为str
命令,通过修补它来使用unicode
反而。这是必要的,因为我们假装我们无法访问b.py
的代码。它可能是一个巨大的包,我们只是使用并且无法更改。但是我们可以插入要调用的新代码来改变行为。
一个现实世界的例子来自 格事件
>>> import gevent
>>> from gevent import socket
>>> urls = ['www.google.com', 'www.example.com', 'www.python.org']
>>> jobs = [gevent.spawn(socket.gethostbyname, url) for url in urls]
>>> gevent.joinall(jobs, timeout=2)
>>> [job.value for job in jobs]
['74.125.79.106', '208.77.188.166', '82.94.164.162']
上面的示例使用 gevent.socket 进行套接字操作。如果
如果使用标准插座模块,则需要花费 3 倍的时间才能完成
完整的,因为 DNS 请求是连续的。使用
greenlets 内的标准套接字模块使 gevent 毫无意义,
那么构建在套接字之上的模块和包又如何呢?
这就是猴子修补的目的。 gevent.monkey 中的函数
仔细替换标准套接字模块中的函数和类
与他们的合作伙伴。这样即使模块
不知道 gevent 可以从在 multi-greenlet 中运行中受益
环境。
>>> from gevent import monkey; monkey.patch_socket()
>>> import urllib2 # it's usable from multiple greenlets now
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)