Python每日一练:猴子补丁

monkey patch允许在运行期间动态修改一个类或模块

猴子补丁是一项允许在运行时(runtime)更改对象行为的技术。 它是一个非常有用的功能,但它也可能使你的代码更难以理解和调试,因此,在实现猴子补丁程序时必须谨慎。

猴子补丁与Python中的灵活性紧密相关。 自定义对象是可变的,因此可以替换其属性而无需创建该对象的新副本。

  • 在运行时替换方法、属性等
  • 在不修改第三方代码的情况下增加原来不支持的功能
  • 在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加
class A:
    def func(self):
        print('这是A类下的func方法')

# arg 这个参数是没有用到的,因为func有一个参数,如果这个函数没有参数的话不能这样直接赋值
def monkey_func(arg):
    print('这是猴子补丁方法')

if __name__ == '__main__':
    a = A()
    # 运行原类下的方法
    a.func()  # 这是A类下的func方法

    # 在不改变原类代码的情况下,动态修改原类的方法,打补丁
    A.func = monkey_func

    # 运行替换后的方法
    a.func()  # 这是猴子补丁方法

应用

gevent通过打补丁的方式,利用自己的socket替换了python的标准socket模块,利用gevent协程处理高并发的情况

from gevent import monkey
monkey.patch_all()
import gevent
from socket import *


def talk(conn):
    while 1:  # 循环通讯
        try:
            from_client_msg = conn.recv(1024)
            if not from_client_msg:break
            print("来自客户端的消息:%s" %(from_client_msg))
            conn.send(from_client_msg.upper())
        except:
            break
    conn.close()


if __name__ == '__main__':
    server = socket()
    ip_port = ("127.0.0.1", 8001)
    server.bind(ip_port)
    server.listen(5)
    while 1:  # 循环连接
        conn, addr = server.accept()
        gevent.spawn(talk, conn)  # 开启一个协程
    server.close()