python 面试题10 猴子补丁(Monkey Patch)

为什么叫猴子补丁?

1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。

属性在运行时的动态替换,叫做猴子补丁(Monkey Patch)。

猴子补丁主要有以下几个用处:

  • 在运行时替换方法、属性等

  • 在不修改第三方代码的情况下增加原来不支持的功能

  • 在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加

可以知道猴子补丁的主要功能便是在不去改变源码的情况下而对功能进行追加和变更;对于编程过程中使用一些第三方不满足需求的情况下,使用猴子补丁是非常方便的。

猴子补丁,算是编程中的一个技巧了。

consider a class that has a method get_data. 
This method does an external lookup (on a database or web API, 
for example), and various other methods in the class call it. 
However, 
in a unit test, you don't want to depend on the external data source 
so you dynamically replace the get_data method with a stub that 
returns some fixed data.

假设一个类有一个方法get_data。这个方法做一些外部查询(如查询数据库或者Web API等),
类里面的很多其他方法都调用了它。
然而,在一个单元测试中,你不想依赖外部数据源。所以你用哑方法态替换了这个get_data方法
哑方法只返回一些测试数据。

案例

class Foo(object):
    def bar(self):
        print('Foo.bar')

​def bar(self):

    print('Modified bar')

Foo().bar()

Foo.bar = bar

Foo().bar()


# Foo.bar
# Modified bar

另一个例子引用了,Zope wiki上对Monkey Patch解释:

from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
    return "ook ook eee eee eee!"

SomeClass.speak = speak
实例 python自定义对象转json串

python自带的json包不支持自定义对象转json串,在python中用json.dumps转自定义对象时会报异常class is not JSON serializable,通过增加一段代码补丁(称作猴子补丁)便可实现自定义转换,补丁代码如下:

from json import JSONEncoder
    def _default(self, obj):
        return getattr(obj.__class__, "to_json", _default.default)(obj)
    _default.default = JSONEncoder().default
    default.JSONEncoder.default = _default

同时在自定义对象里面实现to_json方法。

class Tmp:
    def __init__(self, id, name):
        self.id = id
        self.name = name

    def to_json():
        # 返回自定义对象json串
        pass
最后保证补丁代码在自定义对象转json之前执行过一次即可。

通过补丁代码我们可以看到,
代码替换了json包的默认转json的方法,运行了补丁代码后,转json的过程变成了先找对象的to_json属性,在没有to_json属性的情况下才使用默认的JSONEncoder.default的方法,也就是通过这么一个patch,增加了json包原来没有的功能。

文章参考
https://blog.csdn.net/fly910905/article/details/77152110
https://www.jianshu.com/p/f1060b22aab8
——感谢各位大佬!

扫描二维码关注公众号,回复: 2467165 查看本文章

猜你喜欢

转载自blog.csdn.net/weixin_41853490/article/details/81262563