国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

python與編碼

2019-11-14 17:01:01
字體:
來源:轉載
供稿:網友

Python中的文字對象

Python 3.x中處理文字的對象有str, bytes, bytearray。

  • bytes和bytearray可以使用除了用作格式化的方法(format, format_map)以及幾個特殊的基于Unicode的方法(casefold, isdecimal, isidentifier, isnumeric, isPRintable, encode)以外幾乎所有str的方法。
  • bytes有一個類方法,可以通過序列來構建字符串,而這個方法不可以用在str上。

    >>> b = bytes.fromhex('E4 B8 AD')>>> bb'/xe4/xb8/xad'>>> b.decode('utf-8')'中'>>> str(b)"b'//xe4//xb8//xad'"

    Unicode和字符轉換

    采用chr可以把一個Unicode的code point轉換為字符,通過ord可以進行反向操作。

    >>> ord('A')65>>> ord('中')20013>>> chr(65)'A'>>> chr(20013)'中'

len函數計算的是字符數,不是字節數

>>> len('中')1>>> '中'.encode('utf-8')b'/xe4/xb8/xad'>>> len('中'.encode('utf-8'))    #計算的是bytes對象的長度,包含3個整數字符3

Python與編碼

Python內部處理編碼的方式

在Python接受我們的輸入時,總是會先轉為Unicode。而且這個過程越早越好。
然后Python的處理總是對Unicode進行的,在這個過程中,一定不要進行編碼轉換的工作。
在Python向我們返回結果時,總是會從Unicode轉為我們需要的編碼。而且這個過程越晚越好。

Python源碼的編碼方式

Python默認使用utf-8編碼。
如果想使用一種不同的編碼方式來保存Python代碼,我們可以在每個文件的第一行或者第二行(如果第一行被hash-bang命令占用了)放置編碼聲明(encoding declaration)
# ‐*‐ coding: windows‐1252 ‐*‐

Python中使用的編碼

C:/Users/JL>chcp        #查找操作系統使用的編碼Active code page: 936>>> import sys, locale>>> locale.getpreferredencoding()    #這個是最重要的'cp936'>>> my_file = open('cafe.txt','r')>>> type(my_file)<class '_io.TextIOWrapper'>>>> my_file.encoding    #文件對象默認使用locale.getpreferreddecoding()的值'cp936'>>> sys.stdout.isatty(), sys.stdin.isatty(), sys.stderr.isatty()    #output是否是控制臺console(True, True, True)>>> sys.stdout.encoding, sys.stdin.encoding, sys.stderr.encoding    #sys的標準控制流如果被重定向,或者定向到文件,那么編碼將使用環境變量PYTHONIOENCODING的值、控制臺console的編碼、或者locale.getpreferredencoding()的編碼,優先級依次減弱。('cp936', 'cp936', 'cp936')>>> sys.getdefaultencoding()    #如果Python需要把二進制數據轉為字符對象,那么在缺省情況下使用該值。'utf-8'>>> sys.getfilesystemencoding()    #Python用來編碼或者解碼文件名(不是文件內容)的時候,默認使用該編碼。'mbcs'

以上是在Windows中的測試結果,如果在GNU/linux或者OSX中,那么所有的結果都是UTF-8.
關于mbcs和utf-8的區別,可以參考http://stackoverflow.com/questions/3298569/difference-between-mbcs-and-utf-8-on-windows

文件讀寫的編碼

>>> pen('cafe.txt','w',encoding='utf-8').write('café')4>>> fp = open('cafe.txt','r')>>> fp.read()'caf茅'>>> fp.encoding'cp936'>>> open('cafe.txt','r', encoding = 'cp936').read()'caf茅'>>> open('cafe.txt','r', encoding = 'latin1').read()'caf??'>>> fp = open('cafe.txt','r', encoding = 'utf-8')>>> fp.encoding'utf-8'

從上面的例子可以看出,無論什么時候都不要使用默認的編碼,因為在不同的機器上運行的時候會出現意想不到的問題。

Python如何處理來自Unicode的麻煩

Python總是通過code point來比較字符串的大小,或者是否相等的。

  • Unicode中重音符號有兩種表示方法,用一個字節表示,或者用基字母加上重音符號表示,在Unicode中他們是相等的,但是在Python中由于通過code point來比較大小,所以就不相等了。

    >>> c1 = 'cafe/u0301'>>> c2 = 'café'>>> c1 == c2False>>> len(c1), len(c2)(5, 4)

    解決方法是通過unicodedata庫中的normalize函數,該函數的第一個參數可以接受"NFC",'NFD','NFKC','NFKD'四個參數中的一個。
    NFC(Normalization Form Canonical Composition):以標準等價方式來分解,然后以標準等價重組之。若是singleton的話,重組結果有可能和分解前不同。盡可能的縮短整個字符串的長度,所以會把'e/u0301'2個字節壓縮到一個字節'é'。
    NFD(Normalization Form Canonical Decomposition):以標準等價方式來分解
    NFKD(Normalization Form Compatibility Decomposition):以相容等價方式來分解
    NFKC(Normalization Form Compatibility Composition):以相容等價方式來分解,然后以標準等價重組之。
    NFKC和NFKD可能會引起數據損失。

from unicodedata import normalize>>> c3 = normalize('NFC',c1)        #把c1往字符串長度縮短的方向操作>>> len(c3)4>>> c3 == c2True>>> c4 = normalize('NFD',c2)>>> len(c4)5>>> c4 == c1True

西方的鍵盤通常會鍵入盡可能短的字符串,也就是說和"NFC"的結果一致,但是通過"NFC"來操作一下再比較字符串是否相等比較安全。且W3C建議使用"NFC"的結果。

  • 同樣的一個字符在Unicode中有兩個不同的編碼。
    該函數會把一個單一的Unicode字符轉為另一個Unicode字符。

    >>> o1 = '/u2126'>>> o2 = '/u03a9'>>> o1, o2('?', 'Ω')>>> o1 == o2False>>> name(o1), name(o2)('OHM SIGN', 'GREEK CAPITAL LETTER OMEGA')>>> o3 = normalize('NFC',o1)>>> name(o3)'GREEK CAPITAL LETTER OMEGA'>>> o3 == o2True

    又比如

    >>> u1 = '/u00b5'>>> u2 = '/u03bc'>>> u1,u2('μ', 'μ')>>> name(u1), name(u2)('MICRO SIGN', 'GREEK SMALL LETTER MU')>>> u3 = normalize('NFKD',u1)>>> name(u3)'GREEK SMALL LETTER MU'

    再一個例子

    >>> h1 = '/u00bd'>>> h2 = normalize('NFKC',h1)>>> h1, h2('?', '1?2')>>> len(h1), len(h2)(1, 3)
  • 有時候我們希望使用不區分大小寫的形式進行比較
    使用方法str.casefold(),該方法會把大寫字母轉換為小寫進行比較,比如'A'會轉為'a','MICRO SIGN'的'μ'會轉換為'GREEK SMALL LETTER MU'的'μ'
    在絕大部分(98.9%)情況下str.casefold()和str.lower()的結果一致。

  • 文字排序
    由于不同的語言規則,如果單純按照Python的比較code point的方式進行,那么會出現很多不是用戶期望的結果。
    通常采用locale.strxfrm進行排序。

    >>> import locale>>> locale.setlocale(locale.LC_COLLATE,'pt_BR.UTF-8')'pt_BR.UTF-8'>>> sort_result = sorted(intial, key = locale.strxfrm)

    編碼解碼錯誤

    如果是Python源碼中出現了解碼錯誤,那么會產生SyntaxError異常。
    其他情況下,如果發現編碼解碼錯誤,那么會產生UnicodeEncodeError, UnicodeDecodeError異常。

幾個摘自fluent python中的有用方法

from unicodedata import normalize, combiningdef nfc_equal(s1, s2):    '''return True if string s1 is eual to string s2 after normalization under "NFC" '''    return normalize("NFC",s1) == normalize("NFC",s2)def fold_equal(s1, s2):    '''return True if string s1 is eual to string s2 after normalization under "NFC" and casefold()'''    return normalize('NFC',s1).casefold() == normalize('NFC',s2).casefold()def shave_marks(txt):    '''Remove all diacritic marks    basically it only need to change Latin text to pure ASCII, but this func will change Greek letters also    below shave_latin_marks func is more precise'''    normal_txt = normalize('NFD',txt)    shaved = ''.join(c for c in normal_txt if not combining(c))    return normalize('NFC',shaved)def shave_latin_marks(txt):    '''Remove all diacritic marks from Latin base characters'''    normal_txt = normalize('NFD',txt)    keeping = []    latin_base=False    for c in normal_txt:        if combining(c) and latin_base:            continue    #Ingore diacritic marks on Latin base char        keeping.append(c)        #If it's not combining char, it should be a new base char        if not combining(c):            latin_base = c in string.ascii_letters

編碼探嗅Chardet

這是Python的標準模塊。

參考資料:

  1. http://blog.csdn.net/tcdddd/article/details/8191464

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 繁峙县| 黑龙江省| 阿拉善右旗| 瑞昌市| 武强县| 益阳市| 太保市| 金华市| 新干县| 黎川县| 云龙县| 花垣县| 西乌| 开封市| 沂南县| 金溪县| 根河市| 容城县| 横峰县| 乌恰县| 始兴县| 灵川县| 德令哈市| 木里| 日土县| 诸城市| 元谋县| 济源市| 饶阳县| 宝山区| 图们市| 康保县| 桂东县| 五莲县| 内丘县| 龙里县| 南靖县| 高雄县| 兰州市| 乐都县| 砀山县|