最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python黑魔法之編碼轉換

 更新時間:2016年01月25日 16:09:28   作者:icedoom  
這篇文章主要介紹了python黑魔法之編碼轉換,分析了python編碼轉換的方法,感興趣的小伙伴們可以參考一下

我們在使用其他語言的庫做編碼轉換時,對于無法理解的字符,通常的處理也只有兩種(或三種):

  • 拋異常
  • 替換成替代字符
  • 跳過

但是在復雜的現(xiàn)實世界中,由于各種不靠譜,我們處理的文本總會出現(xiàn)那么些不和諧因素,比如混合編碼。在這種情況下,又回到了上面的處理辦法。

那么問題來了,python有沒有更好地辦法呢?

答案是,有!

python的編碼轉換流程實際上是兩段式轉換:

source -> unicode -> dest

首先將字符串從原始編碼轉換成unicode。再將unicode轉換成目標編碼。

第一步我們一般采用decode()或者 unicode() 這兩個函數(shù)完成。
第二步我們使用encode()函數(shù)完成。

在這里我們說的黑魔法就是在第一步實現(xiàn)。

decode和unicode函數(shù)都有一個叫做errors的可選參數(shù)??纯垂俜降拿枋觯?/p>

  • errors may be given to set a different error
  • handling scheme. Default is 'strict' meaning that encoding errors raise
  • a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
  • as well as any other name registered with codecs. register_error that is
  • able to handle UnicodeDecodeErrors.

這個參數(shù)通常有三種值:

  • strict 默認值。如果出現(xiàn)編碼錯誤,則會拋出UnicodeDecodeError。
  • ignore 跳過。
  • replace 用?替換。

好了,看到最后一句話了嗎?好戲上演了!

模塊codec有一個函數(shù)叫做register_error。他的作用讓用戶可以注冊自定義的errors處理方法。
用來處理UnicodeDecodeError。

我們看看函數(shù)原型:

codecs.register_error(name, error_handler)

name: 錯誤處理的名稱。用以填寫在decode函數(shù)的error參數(shù)中。
error_handler: 處理函數(shù)。該函數(shù)接受一個異常參數(shù)。
返回一個tuple,該tuple有2個元素,第一個是糾錯后的字符串,第二個是繼續(xù)decode的起始位置

有了上面的基本概念。我們看下具體實現(xiàn):

def cjk_error(e):
  if not isinstance(e, UnicodeDecodeError):
    raise TypeError("don't know how to handle %r" % exc) 
  if exc.end + 1 > len(exc.object): 
    raise TypeError('unknown codec ,the object too short!') 
  ch1 = ord(exc.object[exc.start:exc.end]) 
  newpos = exc.end + 1 
  ch2 = ord(exc.object[exc.start + 1:newpos]) 
  sk = exc.object[exc.start:newpos] 
  if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK 
    return (unicode(sk,'cp936'), newpos) 
  if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5 
    return (unicode(sk,'big5'), newpos) 
  raise TypeError('unknown codec !') 
codecs.register_error("cjk_replace", cjk_replace) 

上面這個是我從網上copy的。開始我覺得很不錯,但是后來發(fā)現(xiàn)是個很不經推敲的算法。
比如utf8和gbk在前兩個字節(jié)就有交集的部分。當一個utf8的字符串以gbk編碼decode的時候,出現(xiàn)錯誤是從第三個字節(jié)開始(前兩個字節(jié)也能夠在gbk編碼范圍中對應到一個漢字)。
如:

a = "你"              # utf8編碼:'\xe4\xbd\xa0'
c = unicode(a[:2],'gbk')  # 正常返回
c = unicode(a, 'gbk')    # UnicodeDecodeError 。錯誤發(fā)生在第三個字節(jié)

所以針對這種情況,做了下改進:

import codec

def cjk_replace(e):
  if not isinstance(e, UnicodeDecodeError):
    raise TypeError("invalid exception type %s" e)

  src = e.encoding
  if src in ('gbk','gb18030', 'big5'):
    beg = e.start - 2
    if beg >= 0:
      try:
        return unicode(e.object[beg:e.end], 'utf8'), e.end + 1
      except:
        pass

  if exc.end + 1 > len(exc.object):
    raise TypeError('unknown codec ,the object too short!')
  ch1 = ord(exc.object[exc.start:exc.end])
  newpos = exc.end + 1
  ch2 = ord(exc.object[exc.start + 1:newpos])
  sk = exc.object[exc.start:newpos]

  if src != 'gbk' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK
    return (unicode(sk,'cp936'), newpos)
  if src != 'big5' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5
    return (unicode(sk,'big5'), newpos)
  raise TypeError('unknown codec !')

codecs.register_error("cjk_replace", cjk_replace)

當然,這個邏輯其實還是不夠嚴謹?shù)摹km然對于這種混合編碼這種畸形活處理有點較真兒。
不過既然python提供這樣的能力,大家可以一起來討論下,我們怎么可以做的更好?

相關文章

  • Python查找算法之折半查找算法的實現(xiàn)

    Python查找算法之折半查找算法的實現(xiàn)

    這篇文章主要介紹了Python查找算法之折半查找算法的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • 解決Python paramiko 模塊遠程執(zhí)行ssh 命令 nohup 不生效的問題

    解決Python paramiko 模塊遠程執(zhí)行ssh 命令 nohup 不生效的問題

    這篇文章主要介紹了解決Python paramiko 模塊遠程執(zhí)行ssh 命令 nohup 不生效的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 在Python中使用dict和set方法的教程

    在Python中使用dict和set方法的教程

    這篇文章主要介紹了在Python中使用dict和set方法的教程,dict字典是Python中的重要基礎知識,set與其類似,需要的朋友可以參考下
    2015-04-04
  • Python函數(shù)默認參數(shù)設置的具體方法

    Python函數(shù)默認參數(shù)設置的具體方法

    本文主要介紹了Python函數(shù)默認參數(shù)設置,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • 使用jupyter notebook直接打開.md格式的文件

    使用jupyter notebook直接打開.md格式的文件

    這篇文章主要介紹了使用jupyter notebook直接打開.md格式的文件,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Django項目打包完整步驟以及可能出現(xiàn)的問題

    Django項目打包完整步驟以及可能出現(xiàn)的問題

    django項目的結構大體上都是類似,打包主要的功能就是把一些不需要部署的文件剔除,把需要部署的文件直接壓縮打包,下面這篇文章主要給大家介紹了關于Django項目打包完整步驟以及可能出現(xiàn)問題的相關資料,需要的朋友可以參考下
    2023-06-06
  • Python Unittest自動化單元測試框架詳解

    Python Unittest自動化單元測試框架詳解

    這篇文章主要為大家詳細介紹了Python Unittest自動化單元測試框架的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Numpy數(shù)據(jù)轉換成image并保存的實現(xiàn)示例

    Numpy數(shù)據(jù)轉換成image并保存的實現(xiàn)示例

    本文主要介紹了Numpy數(shù)據(jù)轉換成image并保存的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-12-12
  • python生成多個只含0,1元素的隨機數(shù)組或列表的實例

    python生成多個只含0,1元素的隨機數(shù)組或列表的實例

    今天小編就為大家分享一篇python生成多個只含0,1元素的隨機數(shù)組或列表的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • 如何向scrapy中的spider傳遞參數(shù)的幾種方法

    如何向scrapy中的spider傳遞參數(shù)的幾種方法

    這篇文章主要介紹了如何向scrapy中的spider傳遞參數(shù)的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11

最新評論

泽库县| 南安市| 集贤县| 永丰县| 新和县| 金川县| 闽清县| 乌鲁木齐市| 应城市| 长沙市| 元江| 东明县| 建湖县| 南澳县| 波密县| 鹿邑县| 英德市| 昔阳县| 桓台县| 石渠县| 江津市| 行唐县| 永嘉县| 抚宁县| 玛纳斯县| 南阳市| 新野县| 汨罗市| 龙山县| 广东省| 金平| 蒙山县| 泸溪县| 吉水县| 永胜县| 江陵县| 泗阳县| 蒲江县| 恭城| 谢通门县| 柳州市|