In Python, the term monkey patch
only refers to dynamic modifications of a class or module at runtime, As a beginner its really difficult to me understand this
Monkey-patching is a way to make some global under-the-hood change in a way that existing code will continue to run, but with modified behavior.
str
command: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
module has modified the behavior of other code using the str
command, by patching it to use unicode
instead. This would be necessary since we pretend that we have no access to b.py
's code. It could have been a huge package that we simply use and can't change. But we can slip in new code to be called that changes the behavior.
>>> 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']
The example above used gevent.socket for socket operations. If the standard socket module was used it would took it 3 times longer to complete because the DNS requests would be sequential. Using the standard socket module inside greenlets makes gevent rather pointless, so what about module and packages that are built on top of socket?
That’s what monkey patching for. The functions in gevent.monkey carefully replace functions and classes in the standard socket module with their cooperative counterparts. That way even the modules that are unaware of gevent can benefit from running in multi-greenlet environment.
>>> from gevent import monkey; monkey.patch_socket() >>> import urllib2 # it's usable from multiple greenlets now
There are some real life examples when monkey patching is used:
Object.method1()
behaviour. Method can return a string or None. So here's monkey patching comes. You replace method1
with a stub method containing only one line of code return None
.setattr
function. Well, this often means bad architecture of your application, and is not a good design decision.