0 猴子补丁 - Monkey Patching

  1 定义,
  2     猴子补丁(monkey patching)
  3        在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。猴子补丁在代码运行时
  4         (内存中)发挥作用,不会修改源码,因此只对当前运行的程序实例有效。
  5         因为猴子补丁破坏了封装,而且容易导致程序与补丁代码的实现细节紧密耦合,
  6         所以被视为临时的变通方案,不是集成代码的推荐方式。
  7
  8     monkey patching
  9         Dynamically changing a module, class or function at run time,
 10         usually to add features or fix bugs. Because it is done in memory
 11         and not by changing the source code, a monkey patch only affects the
 12         currently running instance of the program. Monkey patches break
 13         encapsulation and tend to be tightly coupled to the implementation
 14         details of the patched code units, so they are seen as temporary
 15         work-arounds and not a recommended technique for code integration.
 16
 17
 18     猴子补丁的名声不太好。如果滥用,会导致系统难以理解和维护。补丁通常与目标紧密耦合,
 19     因此很脆弱。另一个问题是,打了猴子补丁的两个库可能相互牵绊,因为第二个库可能撤销
 20     了第一个库的补丁。不过猴子补丁也有它的作用,例如可以在运行时让类实现协议。
 21     适配器设计模式通过实现全新的类解决这种问题。为 Python 打猴子补丁不难,但是有些局限。
 22     与 Ruby 和 JavaScript 不同, Python 不允许为内置类型打猴子补丁。
 23     其实这是优点,因为这样可以确保 str 对象的方法始终是那些。
 24     这一局限能减少外部库打的补丁有冲突的概率。
 25
 26 看例子之前, 回顾一下儿 协议 protocol,
 27     详见 duck typing 一文,
 28         http://www.cnblogs.com/zzyzz/p/7723272.html
 29         在 Python 中创建功能完善的序列类型无需使用继承, 只需实现符合序列协议的方法.
 30         在面向对象编程中,协议是非正式的接口,只在文档中定义,在代码中不定义.
 31         例如,Python 的序列协议只需要 __len__ 和 __getitem__ 两个方法.
 32         任对象/类型(A)只要使用标准的签名和语义实现了这两个方法,就能用在任何期待序列的地方,
 33         然而A 是不是哪个类的子类无关紧要,只要提供了所需的方法即可.这就是 python 序列协议.
 34         协议是非正式的,没有强制力,因此如果你知道类的具体使用场景,通常只需要实现一个协议的部分.
 35         例如,为了支持迭代,只需实现 __getitem__ 方法,没必要提供 __len__方法.
 36
 37 例子,
 38     注意 '>>>' 表示在交互式控制台 console 的输入
 39     >>>class ballgame(object):              # 这个class 可以生成一个 ball 的组合集合.
 40     ...    colors = ['red','green','bule']
 41     ...    boxs = ['1', '2', '3']
 42
 43     ...    def __init__(self):
 44     ...        self.ballsets = [(b, c) for b in self.boxs for c in self.colors]
 45
 46     ...    def __getitem__(self, position):
 47     ...        return self.ballsets[position]
 48
 49     ...    def __len__(self):
 50     ...        return len(self.ballsets)
 51
 52         # def __setitem__(self, key, value):
 53         #     self.ballsets[key] = value
 54     ...   def pickone(self,position):
 55     ...        return self.ballsets[position]
 56
 57     >>>ball = ballgame()
 58     >>>ball.ballsets
 59     [('1', 'red'), ('1', 'green'), ('1', 'bule'), ('2', 'red'), ('2', 'green'),
 60     ('2', 'bule'), ('3', 'red'), ('3', 'green'), ('3', 'bule')]
 61     >>>ball.pickone(2)
 62     ('1', 'bule')             # 这里会发现主要取得位置相同, 取出的 ball 组合就不变.
 63                               # 我们是通过 random 模块重新排序 ball 示例中 ball 组合的顺序.
 64     >>>import random
 65     >>>random.shuffle(ball)
 66     Traceback (most recent call last):
 67     File "<input>", line 1, in <module>
 68     File "C:\Users\yzzhou8\AppData\Local\Programs\Python\Python36-32\lib\random.py", line 274, in shuffle
 69     x[i], x[j] = x[j], x[i]
 70     TypeError: 'ballgame' object does not support item assignment
 71
 72     #发现 random.shuffle 不可行,原因是 ballgame 类中没有实现可变序列协议的 __setitem__ 方法,
 73     #当然可以通过在类中实现 __setitem__ 特殊方法后,重新初始化实例解决这个问题,
 74     #现在看看如果通过 monkey patching 解决这个问题.
 75
 76     >>>def setballset(ballgame,position,ballset):
 77     ...    ballgame.ballsets[position] = ballset
 78
 79     >>>ball.__setitem__ = setballset
 80     >>>random.shuffle(ball)
 81     >>>ball.ballsets
 82     [('1', 'bule'), ('1', 'green'), ('2', 'bule'), ('3', 'green'), ('2', 'green'),
 83     ('2', 'red'), ('1', 'red'), ('3', 'red'), ('3', 'bule')]
 84     >>>random.shuffle(ball)
 85     ball.ballsets
 86     [('1', 'green'), ('3', 'red'), ('3', 'green'), ('1', 'red'), ('2', 'green'),
 87     ('3', 'bule'), ('2', 'red'), ('2', 'bule'), ('1', 'bule')]
 88
 89     # 通过 monkey patching 在 ballgame 类的实例 ball 中 实现了 __setitem__ 特殊方法,
 90     # 使 ball 实例变成一个符合可变序列协议的的实例,进而使我们可以通过 random.shuffle(ball)
 91     # 来重新排序 ball.ballsets
 92
 93     >>>ball2 = ballgame()
 94     >>>random.shuffle(ball2)
 95     Traceback (most recent call last):
 96     File "<input>", line 1, in <module>
 97     File "C:\Users\yzzhou8\AppData\Local\Programs\Python\Python36-32\lib\random.py", line 274, in shuffle
 98     x[i], x[j] = x[j], x[i]
 99     TypeError: 'ballgame' object does not support item assignment
100
101     # Monkey patching 并没有在原来类中起作用.
102
103     summarize, Monkey patching 之所以起作用, 要得益于 duck typing,
104         然而, 最终要归功于 python 的 协议protocol 这一架构设计.

转载于:https://www.cnblogs.com/zzyzz/p/7728249.html

猴子补丁 - Monkey Patching相关推荐

  1. python的猴子补丁(Monkey Patching)

    0. 参考文档 参考文档如下: https://achowdhary.com/monkey-patching/ https://www.cnblogs.com/xp1315458571/p/16049 ...

  2. 27.Python中的猴子补丁 (Monkey Patching)

    <Python编程的术与道:Python语言进阶>视频课程 <Python编程的术与道:Python语言进阶>视频课程链接:https://edu.csdn.net/cours ...

  3. 猴子补丁(Monkey Patching)

    猴子补丁是我在面试的时候接触的一到题,学python的时候,我根本就没有听说这个概念!那接下来我们来分析一下: 1.什么是猴子补丁? 2.猴子补丁的功能? 3.猴子补丁的应用场景? 一.什么是猴子补丁 ...

  4. python猴子补丁_Python猴子补丁Monkey Patch用法实例解析

    属性在运行时的动态替换,叫做猴子补丁(Monkey Patch). 为什么叫猴子补丁 属性的运行时替换和猴子也没什么关系,关于猴子补丁的由来网上查到两种说法: 1.这个词原来为Guerrilla Pa ...

  5. python画猴子_Python猴子补丁Monkey Patch用法实例解析

    属性在运行时的动态替换,叫做猴子补丁(Monkey Patch). 为什么叫猴子补丁 属性的运行时替换和猴子也没什么关系,关于猴子补丁的由来网上查到两种说法: 1.这个词原来为Guerrilla Pa ...

  6. 什么是猴子补丁(monkey patch)

    monkey patch指的是在运行时动态替换,一般是在startup的时候. 用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all();把标准库中的thread/ ...

  7. python 猴子补丁_python面试题精讲——monkey patch(猴子补丁)

    前言本次依然是选自python面试题系列,将一个比较偏的概念,可能很多人没怎么听说过--猴子补丁,其实所讲的内容很简单,它得益于python灵活的语法.一切皆对象的思想,一起来看看看看吧!目录一.什么 ...

  8. Python面试题之“猴子补丁”(monkey patching)指的是什么?这种做法好吗?

    "猴子补丁"就是指,在函数或对象已经定义之后,再去改变它们的行为. 举个例子: import datetime datetime.datetime.now = lambda: da ...

  9. Python中的Monkey Patch(猴子补丁)

    一.猴子补丁的介绍 关于猴子补丁为啥叫猴子补丁,据说是这样子的: 这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是"杂牌军补丁(gueri ...

最新文章

  1. 枚举 ---- B. Power Sequence[Codeforces Round #666 (Div. 2)][暴力]
  2. 单线程下的生产者--消费者模式详解,wait和sleep的区别
  3. 类型与通用语言运行时
  4. php 求数组合集,PHP数组排序函数合集 以及它们之间的联系分析
  5. mysql flask-login_Flask框架通过Flask_login实现用户登录功能示例
  6. centos 7配置rsync源服务器
  7. MFC CListCtrl 将一个列表的选中项添加到另一个列表
  8. pythonmt4通讯swot矩阵_SWOT矩阵分析法
  9. 老师必备的数学几何绘图软件,赶紧收藏!
  10. PackageManager.hasSystemFeature Android SystemServer裁剪
  11. 走近篮球运动·体育项目
  12. 设计稿 自动html,简单的登陆页面PSD设计稿来演示转化为HTML页面的全部过程
  13. 激光雷达与自动驾驶详解
  14. access 报表隔行底纹_excel中如何隔行填充底纹
  15. t460p和t470p对比评测_老模具小升级 ThinkPad T470p商务本评测
  16. 在 Linux CentOS7 上安装 Maven
  17. 高德地图小程序步行路线显示_微信小程序 高德地图路线规划实现过程详解
  18. 微信分享第三方连接(H5页面)自定义缩略图、标题、描述(显示分享框,而不是链接)(微信JS-SDK)
  19. android 自动挂断,android项目实现电话自动挂断的功能
  20. 树莓派与STM32通信编码格式

热门文章

  1. 项目费用管理包括哪些内容?
  2. tpshop表结构说明(整理中)
  3. 【Python茴香豆系列】之 如何逆序一个列表
  4. python:函数中五花八门的参数形式(茴香豆的『回』字有四种写法)
  5. 上周技术关注:C# 3.0 Orcas 简介
  6. mastercard 接口_万事达卡(MasterCard)和维萨(Visa)取消了广受欢迎的付款验证计划...
  7. JAVA(android)提取WIFI客流探针MAC地址源码
  8. ei capitan mysql_退出MySQL而不重新启动El Capitan
  9. 没错,华为开始对AI下手了!
  10. Nokia补牢,为时未晚