python 猴子补丁(monkey patch)
作者:d咚咚呛 发布时间:2022-12-25 02:15:13
写了一段时间java切回写python偶尔会出现一些小麻烦,比如:在java中自定义对象变成json串很简单,调用一个方法就行,但同样的转换在python中却不太容易实现。在寻找python自定义对象转json串的过程中,接触到了猴子补丁这个东西,感觉还有点意思;本文先实现python自定义对象转json串,再简单谈一下猴子补丁。
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包原来没有的功能。
猴子补丁
关于猴子补丁为啥叫猴子补丁,据说是这样子的:
这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是“杂牌军补丁(guerilla patch)”,后来guerilla就渐渐的写成了gorllia((猩猩),再后来就写了monkey(猴子),所以猴子补丁的叫法是这么莫名其妙的得来的。
猴子补丁主要有以下几个用处:
在运行时替换方法、属性等
在不修改第三方代码的情况下增加原来不支持的功能
在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加
例如:上面自定义对象转json,在原有json包不满足的条件下,只需要将以上的一个patch写在一个文件里自己再import一次,便可实现自己想要的功能,这是非常方便的。
可以知道猴子补丁的主要功能便是在不去改变源码的情况下而对功能进行追加和变更;对于编程过程中使用一些第三方不满足需求的情况下,使用猴子补丁是非常方便的。
猴子补丁,算是编程中的一个技巧了。
拓展
json包默认转json的过程
可以看一下json包里面转json串的过程:
def _iterencode(o, _current_indent_level):
if isinstance(o, basestring):
yield _encoder(o)
elif o is None:
yield 'null'
elif o is True:
yield 'true'
elif o is False:
yield 'false'
elif isinstance(o, (int, long)):
yield str(o)
elif isinstance(o, float):
yield _floatstr(o)
elif isinstance(o, (list, tuple)):
for chunk in _iterencode_list(o, _current_indent_level):
yield chunk
elif isinstance(o, dict):
for chunk in _iterencode_dict(o, _current_indent_level):
yield chunk
else:
if markers is not None:
markerid = id(o)
if markerid in markers:
raise ValueError("Circular reference detected")
markers[markerid] = o
o = _default(o)
for chunk in _iterencode(o, _current_indent_level):
yield chunk
if markers is not None:
del markers[markerid]
其实就是一连串的if-elif-else,将所有的自建对象都匹配一遍,最后匹配不到的就报错了,所以自定义对象转json自然会有问题。
其他实现自定义对象转json的方法
其实json包的源码文档里面也有很详细的别的自定义对象转json的方法。
r'''
Specializing JSON object decoding::
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> from decimal import Decimal
>>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
True
Specializing JSON object encoding::
>>> import json
>>> def encode_complex(obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... raise TypeError(repr(o) + " is not JSON serializable")
...
>>> json.dumps(2 + 1j, default=encode_complex)
'[2.0, 1.0]'
>>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
'[2.0, 1.0]'
>>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
'[2.0, 1.0]'
'''
来源:https://www.jianshu.com/p/f1060b22aab8
猜你喜欢
- pandas.read_csv参数整理 读取CSV(逗号分割)文件到DataFrame也支持文件的部分导入和选择迭代更多帮助参见:
- 问题:过滤用户输入中前后多余的空白字符‘ ++++abc123---
- 【OpenCV】⚠️高手勿入! 半小时学会基本操作 ⚠️ 图像轮廓概述OpenCV 是一个跨平台的计算机视觉库, 支持多语言, 功能强大.
- 利用 CSS 来实现对象的垂直居中有许多不同的方法,比较难的是选择那个正确的方法。我下面说明一下我看到的好的方法和怎么来创建一个好的居中网站
- 很久没有上过天极网,今天偶然兴起跑上去看了一下,看到消息说天极网深圳站隆重上线,于是也顺便去溜了一把,打开页面的时候差点有种不知所措的感觉,
- 前言对自己写的冗长代码,想重构但又无思路?小编整理了介绍python代码重构优化的一些方法,助你一臂之力。编写干净的 Pythonic 代码
- 目标跟踪是对摄像头视频中的移动目标进行定位的过程,有着非常广泛的应用。实时目标跟踪是许多计算机视觉应用的重要任务,如监控、基于感知的用户界面
- 需要注意的是:更改完源程序.c文件,需要对整个项目重新编译、make install,对已经生成的文件进行更新,类似于之前VS中在一个类中增
- 本文实例为大家分享了python绘制汉诺塔的具体代码,供大家参考,具体内容如下源码:import turtleclass Stack: &n
- jQuery 将马上发布 1.4 正式版,代码也从 googlecode 上迁移到了 github. jQuery 是我接触的第一个 JS
- php 如何获取请求的xml数据,对方通过http协议post提交过来xml数据,php如何获取到这些数据呢?<?php $xml_d
- 前言损失函数在机器学习中用于表示预测值与真实值之间的差距。一般而言,大多数机器学习模型都会通过一定的优化器来减小损失函数从而达到优化预测机器
- Photoshop Express,也就是传说中的web版photoshop,来了。和想象中的web photoshop相比,这个Photo
- 本文实例讲述了Python实例方法、类方法、静态方法的区别与作用。分享给大家供大家参考,具体如下:Python中至少有三种比较常见的方法类型
- 字典简介Python 中字典和集合也是非常相近的概念,而且从外观看上去,也有那么一丝丝的相似,Python 语言中字典类型是非常灵活的,在实
- 前言之前的文章编写了一个返回json的例子,直接用浏览器进行get请求虽然成功了, 但是接口文档的样式很难看, 不好用. 而且提示没有访问权
- 下面代码即是VBScript代码在服务器端编译后的显示内容,如果我们把这段代码保存成静态文件(HTML)或JS文件,那么上一篇提出的问题就迎
- 目录一、== 是比较两个对象的内容是否相等二、is 比较的是两个实例对象是不是完全相同三、使用is注意python对于小整数使用对象池存储问
- ppt要想完美的转pdf,图片,还是需要在windows下面来操作。1,安装python3.5.1下载地址Windows x86-64 ex
- 今天想围绕“产品交互设计”说说一些我们的想法,一说到产品设计,我想在坐的各位脑海里肯定联想到了很多表单设计、导航设计、界面布局等等,但是今天