亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python 猴子補丁(monkey patch)

系統 2361 0

寫了一段時間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]'
'''


          

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 色天天综合 | 日韩欧美视频免费观看 | 国产亚洲精品看片在线观看 | 日产精品久久久一区二区 | 182午夜在线观看 | 激情五月婷婷综合网 | 国产精品乱码免费一区二区 | 国产在线视频二区 | 欧美高清一区 | 国产精品素人福利 | 久青草视频97国内免费影视 | 国产精品原创 | 国产偷视频 | 欧美精品aaa久久久影院 | 乱在线伦视频免费 | 青青爽| 中文字幕久久综合 | 拍拍拍无挡视频免费观看1000 | 97精品国产高清久久久久蜜芽 | 亚洲成在人线中文字幕 | 深夜在线视频 | 四虎影视国产884a精品亚洲 | 国产日韩欧美精品在线 | 四虎影视大全 | 九九99久久精品午夜剧场免费 | 天天射天天干天天插 | 九九精品免费视频 | 婷婷综合亚洲 | 欧美日韩亚洲成人 | 成年人福利网站 | 欧美国产日韩一区二区三区 | 日韩精品另类天天更新影院 | 性综合网 | 久久夜夜 | 一级做a毛片免费视频 | 亚洲精品中文字幕久久久久久 | 女bbbbxxxx毛片视频丶 | 永久黄网站色视频免费 | 国产性生活 | 欧美一欧美一级毛片 | 亚洲精品久久九九热 |