Python 基礎 - 字符轉編碼操作
回顧字符編碼的前世今生
ASCII 只能儲英文或特殊字符,只占一個字節,一個字節8bit,不能儲中文,所以才出現Unicode
Unicode 不管是中文或英文,都是占二個字節,一個字節8bit
UTF-8 是一種針對Unicode的可變長度字元編碼,英文字符一樣會依照ASCII碼規範,只占一個字節8bit,而中文字符的話,統一就占三個字節
回顧可以參考字符編碼
字符編碼解碼流程
圖解當二種不同字符編碼的轉編、解碼的過程,例如我要把一個GBK的字符編碼轉成UTF-8的過程是怎麼轉換的
- 首先通過編碼
decode轉換為Unicode編碼 - 然後通過解碼
encode轉換為UTF-8編碼

那我們就先用utf-8轉gbk,來做實做看看…下面代碼都是先用python2.7版執行
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = '你好'
s_to_unicode = s.decode(encoding='utf-8') # 要告訴decode原本的編碼是哪種
print(s_to_unicode)
----------------------執行結果----------------------
ascii
你好
剛剛上面的代碼只是先做 UTF-8 decode Unicode,不相信!!! 好吧來驗証一下
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = '你好'
s_to_unicode = s.decode(encoding='utf-8') # 要告訴decode原本的編碼是哪種
print(s_to_unicode)
print(s_to_unicode, type(s_to_unicode))
----------------------執行結果----------------------
ascii
你好
(u'\u4f60\u597d', <type 'unicode'>) # 變成一個tuple,所以就不會顯示中文
上面那個看起來很像亂碼(不是亂馬),其實是unicode格式,証明我們已經確實的把 UTF-8 decode Unicode編碼了,再來就是要把 Unicode encode gbk
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = '你好'
s_to_unicode = s.decode(encoding='utf-8')
print(s_to_unicode)
print(s_to_unicode, type(s_to_unicode))
s_to_gbk = s_to_unicode.encode(encoding='gbk')
print(s_to_gbk)
----------------------執行結果----------------------
ascii
你好
(u'\u4f60\u597d', <type 'unicode'>)
���
上面代碼已經完成Unicode encode gbk,但為什麼還是看不到字?那是目前的terminal的編碼依然是utf-8,若想看到���的話,就請修改 iTerm2 → Preference → Profiles → Terminal → Character Encoding → Chinese (GBK),然後執行一次剛剛的代碼,執行的結果會如下
ascii
浣犲ソ
(u'\u4f60\u597d', <type 'unicode'>)
你好
原本第二行的你好變成浣犲ソ,而最後一行的���變成你好,這樣就可以確認我們真的已經完成UTF-8 decode Unicode → Unicode encode gbk,那如果要反向操作的話呢?
Terminal記得再調回成UTF-8,再執行一次
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = '你好'
s_to_unicode = s.decode(encoding='utf-8')
print(s_to_unicode)
print(s_to_unicode, type(s_to_unicode))
s_to_gbk = s_to_unicode.encode(encoding='gbk')
print(s_to_gbk)
print(s_to_gbk, type(s_to_gbk))
gbk_to_utf8 = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8')
print(gbk_to_utf8)
print(gbk_to_utf8, type(gbk_to_utf8))
----------------------執行結果----------------------
ascii
你好
(u'\u4f60\u597d', <type 'unicode'>)
���
('\xc4\xe3\xba\xc3', <type 'str'>)
你好
('\xe4\xbd\xa0\xe5\xa5\xbd', <type 'str'>)
再來動一個小小的手腳,來思考一下
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = u'你好'
print(s)
print(s, type(s))
s_to_unicode = s.decode(encoding='utf-8')
print(s_to_unicode)
print(s_to_unicode, type(s_to_unicode))
s_to_gbk = s_to_unicode.encode(encoding='gbk')
print(s_to_gbk)
print(s_to_gbk, type(s_to_gbk))
gbk_to_utf8 = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8')
print(gbk_to_utf8)
print(gbk_to_utf8, type(gbk_to_utf8))
----------------------執行結果----------------------
ascii
你好
(u'\u4f60\u597d', <type 'unicode'>)
Traceback (most recent call last):
File "encode.py", line 10, in <module>
s_to_unicode = s.decode(encoding='utf-8')
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
咦,u'你好' 這個u是什麼呢?是指unicode,但…為什麼第二行可以被打印出來?是因為…別忘了,UTF-8是Unicode其中一個的擴展集,所以可以正常打印出來utf-8格式,再來要怎麼修改上面出錯的代碼?
# -*- coding:utf-8 -*-
import sys
print(sys.getdefaultencoding()) # 打印出目前系統字符編碼
s = u'你好'
print(s)
print(s, type(s))
s_to_gbk = s.encode(encoding='gbk')
print(s_to_gbk)
print(s_to_gbk, type(s_to_gbk))
gbk_to_utf8 = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8')
print(gbk_to_utf8)
print(gbk_to_utf8, type(gbk_to_utf8))
----------------------執行結果----------------------
ascii
你好
(u'\u4f60\u597d', <type 'unicode'>)
���
('\xc4\xe3\xba\xc3', <type 'str'>)
你好
('\xe4\xbd\xa0\xe5\xa5\xbd', <type 'str'>)
接下來講 Python3 字符轉編碼的操作,先確認Pycharm的字符編碼是 UTF-8(PyCharm Community Edition → Perferences → Editor → File Encodings → IDE Encoding → UTF-8),再來就要開始來實驗了
#!/usr/bin/env python3
import sys
print("目前系統字符編碼:", sys.getdefaultencoding()) # 打印目前系統字符編碼
s = '你好押'
s_to_gbk = s.encode(encoding='gbk')
print(s)
print(s_to_gbk)
----------------------執行結果----------------------
目前系統字符編碼: utf-8
你好押
b'\xc4\xe3\xba\xc3\xd1\xba'
Process finished with exit code 0
上面代碼的確認系統的編碼是utf-8,而你好押 變成了 b'\xc4\xe3\xba\xc3\xd1\xba',在最前面的b指的就是bytes類型,會變成這樣是因為Python3預設就是默認使用Unicode中的utf-8,而我們使用了s.encode(encoding='gbk'),導致它打印出來就是一個bytes類型,不相信!那我們來打印一個是utf-8的bytes類型
#!/usr/bin/env python3
import sys
print("目前系統字符編碼:", sys.getdefaultencoding()) # 打印目前系統字符編碼
s = '你好押'
s_to_gbk = s.encode(encoding='gbk')
print(s)
print(s_to_gbk)
print(s.encode(encoding='utf-8'))
----------------------執行結果----------------------
目前系統字符編碼: utf-8
你好押
b'\xc4\xe3\xba\xc3\xd1\xba'
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\x8a\xbc'
Process finished with exit code 0
唔…上面代碼第三個打印出來真的是utf-8的bytes類型,那再來把gbk轉成utf-8
#!/usr/bin/env python3
import sys
print("目前系統字符編碼:", sys.getdefaultencoding()) # 打印目前系統字符編碼
s = '你好押'
s_to_gbk = s.encode(encoding='gbk')
gbk_to_utf8 = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8') # 先把gbk轉成unicode,再轉成utf-8
print(s)
print(s_to_gbk)
print(s.encode(encoding='utf-8'))
print("utf8:", gbk_to_utf8)
----------------------執行結果----------------------
目前系統字符編碼: utf-8
你好押
b'\xc4\xe3\xba\xc3\xd1\xba'
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\x8a\xbc'
utf8: b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\x8a\xbc'
Process finished with exit code 0
嗯!有發現什麼嗎?沒錯,第三行跟第四行打印出來的結果是一樣的,這樣就証明了這真的就是utf-8的bytes類型,那如果要把第四行還原成字符串,要怎麼弄?
#!/usr/bin/env python3
import sys
print("目前系統字符編碼:", sys.getdefaultencoding()) # 打印目前系統字符編碼
s = '你好押'
s_to_gbk = s.encode(encoding='gbk')
gbk_to_utf8 = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8') # 先把gbk轉成unicode,再轉成utf-8
gbk_to_utf8_str = s_to_gbk.decode(encoding='gbk').encode(encoding='utf-8').decode(encoding='utf-8')
print(s)
print(s_to_gbk)
print(s.encode(encoding='utf-8'))
print("utf8:", gbk_to_utf8)
print("utf8_str:", gbk_to_utf8_str)
----------------------執行結果----------------------
目前系統字符編碼: utf-8
你好押
b'\xc4\xe3\xba\xc3\xd1\xba'
b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\x8a\xbc'
utf8: b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\x8a\xbc'
utf8_str: 你好押
Process finished with exit code 0
知識點:
在Python3因為字串已經全部統一成 unicode ,所以不必在字符串前加上 u ,這是Python2和Python3的重要差別之一,需要特別注意
參考資料:
知識點:
在Python3因為字串已經全部統一成 unicode ,所以不必在字符串前加上 u ,這是Python2和Python3的重要差別之一,需要特別注意
參考資料:
Python 基礎 - 字符轉編碼操作的更多相关文章
- Python 基礎 - 字符編碼
Python 解釋器在加載 .py 文件中的代碼時,會對內容進行編碼 (默認 ascill) ASCII (American Standard Code for Information Interch ...
- Python 基礎 - if else流程判斷
hmm~前面講了那麼多,終於可以稍稍的正式進入另一個階段,沒錯,要開始寫判斷式了 這次先從最簡單的判斷式開始,if else 開始- Go 首先,之前有寫有一個簡單的互動式 用戶輸入 的代碼,忘記了嗎 ...
- Python 基礎 - for流程判斷
今天介紹另一個循環判斷式 for循環,首先,先寫一個很簡單的 for循環的代碼 #!/usr/bin/env python3 # -*- coding:utf-8 -*- for i in range ...
- Python 基礎 - 文件操作_v2
嗯,那如何要把游標的位置給打印來? #!/usr/bin/env python3 # -*- coding:utf-8 -*- f = open('test', 'r') print(f.tell() ...
- Python 基礎 - 字典的操作使用
接下來介紹字典,這在未來工作上,會是很常使用的,就來好好了解一下唄- 字典是一個 key(鍵)-value(值) 的數據類型,可以儲存很多訊息 #!/usr/bin/env python3 # -*- ...
- Python 基礎 - pyc 是什麼
Python2.7 版中,只要執行 .py 的檔案後,即會馬上產生一個 .pyc 的檔案,而在 Python3 版中,執行 .py 的檔案後,即會產生一個叫 __pycache__ 的目錄,裡面也會有 ...
- Python 基礎 - bytes數據類型
三元運算 什麼是三元運算?請看下圖說明 透過上圖說明後,可以得出一個三元運算公式: result = 值1 if 條件 else 值2, 如果鯈件為真: result = 值1 如果鯈件為假: res ...
- python基礎學習第一天
python歷史 Python 是一种解释型.面向对象.动态数据类型的高级程序设计语言.Python 由 Guido van Rossum 于 1989 年底在荷兰国家数学和计算机科学研究所设计出来 ...
- python基礎學習第二天
字符编码 # 需知:## 1.在python2默认编码是ASCII, python3里默认是unicode## 2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf ...
随机推荐
- spark发行版笔记4Spark Streaming事务处理彻底掌握
Spark Streaming事务处理彻底掌握 感谢DT大数据梦工厂支持提供以下内容,DT大数据梦工厂专注于Spark发行版定制. 内容概括: 1Exactly once 2 输出不重复 1 正如银行 ...
- Winform 支持高清屏(High DPI) 设置
http://www.cnblogs.com/weiym/p/3555068.htmlhttp://crsouza.com/2015/04/how-to-fix-blurry-windows-form ...
- 【重要!】告K2老客户书
K2近期升级优化了售后支持系统,以便能更好的为亲爱的老客户们答疑解惑,比如:“老妈和老婆掉水里先救谁”.“中午吃啥晚上吃啥”.“技术男怎么学会撩妹”……这些问题,统统不会告诉你.售后TEAM作为一支专 ...
- 微信公众号网页开发-jssdk config配置参数生成(Java版)
一.配置参数 参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&la ...
- mysql连接查询和子查询
一.连接查询 1.交叉连接 就是从一张表的一条记录去连接另一张表中的所有记录,并且保存所有的记录,其中包括两个表的所有的字段! 从结果上看,就是对两张表做笛卡尔积! 笛卡尔积也就是两个表中所有可能的连 ...
- DevExpress VGridControl 行宽自动调整
1. 让列的宽度自动填充 如果VGridControl的LayoutStyle属性为BandsView或SingleRecordView,那么把VGridControl的OptionsView.Aut ...
- Common.Logging log4net Common.Logging.Log4Net 配置
1.log4net 单独配置 log4net支持多种格式的日志输出,我这里只配置输出到本地的txt文件这种格式. <log4net> <root> <appender-r ...
- ArcEngine 栅格数据
1.ArcEngine中的栅格数据组织方式(详细信息见:http://resources.arcgis.com/zh-cn/help/main/10.1/index.html#/na/009t0000 ...
- 006 复杂的数据类型&函数(方法)
2016-01-16 1.变量类型int double string char bool decimal变量的使用规则:先声明再赋值最后使用int number;number=10; number=2 ...
- Android Service提高
我们从以下几个方面来了解Service IntentService的使用 Service与Thread的区别 Service生命周期 前台服务 服务资源被系统以外回收处理办法 不被销毁的服务 Inte ...