python 猴子补丁_python面试题精讲——monkey patch(猴子补丁)
前言本次依然是選自python面試題系列,將一個比較偏的概念,可能很多人沒怎么聽說過——猴子補丁,其實所講的內容很簡單,它得益于python靈活的語法、一切皆對象的思想,一起來看看看看吧!目錄一、什么是monkey patch
二、monkey patch的功能簡介
2.1 運行時動態改變類的方法
2.2 monkey patch的應用場景
一、什么是monkey patch
為什么叫猴子補丁?這其實是一個很難回答的問題,似乎和Python語言沒啥關系,而且也和它所實現的功能扯不上什么關系,但是偏偏就這么叫了,那就姑且這么稱呼吧。
關于猴子補丁的由來網上查到兩種說法:1,這個詞原來為Guerrilla Patch,雜牌軍、游擊隊,說明這部分不是原裝的,在英文里guerilla發音和gorllia(猩猩)相似,再后來就寫了monkey(猴子)。
2,還有一種解釋是說由于這種方式將原來的代碼弄亂了(messing with it),在英文里叫monkeying about(頑皮的),所以叫做Monkey Patch。
外國人有時候總是會給一些概念莫名其妙的稱呼,這就不管他了,關鍵是理解它的本質和功能才是最重要的。
先明確一個觀點:猴子補丁(monkey patch)的主要功能就是動態的屬性的替換。雖然屬性的運行時替換和猴子也沒什么關系,所以說猴子補丁的叫法有些莫名其妙,但是只要和“模塊運行時替換的功能”對應就行了。
二、monkey patch的功能簡介
monkey patch允許在運行期間動態修改一個類或模塊(注意python中一切皆對象,包括類、方法、甚至是模塊)
2.1 運行時動態改變類的方法
先看一個簡單的例子:class?A:
def?func(self):
print('Hi')
def?monkey(self):
print('Hi,?monkey')
a?=?A()
a.func()
'''運行結果
Hi
'''
上面的結果無可厚非,大家都知道,但是看一下下面的例子:class?A:
def?func(self):
print('Hi')
def?monkey(self):
print('Hi,?monkey')
a?=?A()
A.func=A.monkey???#在運行的時候,才改變了func
a.func()
'''運行結果
Hi,?monkey
'''
就這么簡單,其實這根本的原因在于Python語法的靈活性,方法可以像普通對象那樣使用。
我們還可以這樣做:class?A:
def?func(self):
print('Hi')
def?monkey(self):
print('Hi,?monkey')
def?outer_monkey(a):??#?a?這個參數是沒有用到的,因為func有一個參數,如果這個函數沒有參數的話不能這樣直接賦值
print('Hi,outer?monkey')
a?=?A()
A.func=outer_monkey
a.func()
'''運行結果
Hi,?outer?monkey
'''
將類外面的普通方法依然可以在程序運行的時候動態賦值給類的某一個方法。
總結:上面所展示的其實就是monkey patch,即運行時動態改變方法、類的方法。其實不管是定義在類外的普通方法、類里面的方法、甚至是模塊這些都可以進行“動態替換的操作”,不得不感嘆python真的是一門簡潔靈活的語言。
2.2 monkey patch的應用場景
這里有一個比較實用的例子,很多代碼用到 import json,后來發現ujson性能更高,如果覺得把每個文件的import json 改成 import ujson as json成本較高,或者說想測試一下用ujson替換json是否符合預期,只需要在入口加上:import?json
import?ujson
def?monkey_patch_json():
json.__name__?=?'ujson'
json.dumps?=?ujson.dumps
json.loads?=?ujson.loads
monkey_patch_json()
其實這種場景也比較多,比如我們引用團隊通用庫里的一個模塊,又想豐富模塊的功能,除了繼承之外也可以考慮用Monkey Patch。個人感覺Monkey Patch帶了便利的同時也有搞亂源代碼優雅的風險。猜您喜歡
總結
以上是生活随笔為你收集整理的python 猴子补丁_python面试题精讲——monkey patch(猴子补丁)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python-OpenCV 笔记5 --
- 下一篇: Anaconda 安装与使用