python2編碼總結

来源:http://www.cnblogs.com/jinhaolin/archive/2016/01/14/5128973.html
-Advertisement-
Play Games

以下依次列出python2常遇到的幾個問題及講解。# -*- coding:utf-8 -*-python2預設以ASCII編碼,但是在實際編碼過程中,我們會用到很多中文,為了不使包含中文的程式報錯,也是為了符合國際通用慣例,一般將我們的文件編碼設置為utf-8格式。設定編碼的格式有很多種,只要第一...


以下依次列出python2常遇到的幾個問題及講解。

 

# -*- coding:utf-8 -*-

python2預設以ASCII編碼,但是在實際編碼過程中,我們會用到很多中文,為了不使包含中文的程式報錯,也是為了符合國際通用慣例,一般將我們的文件編碼設置為utf-8格式。

設定編碼的格式有很多種,只要第一行或者第二行的聲明符合正則表達式 "coding[:=]\s*([-\w.]+)" 即可,一般的聲明方式為#-*- coding:utf-8 -*-。

str = "你好"
print str

  運行以上代碼,程式會報錯:SyntaxError: Non-ASCII character '\xe4' in file D:/TestPython/test/111.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details。這是提示程式中有非ASCII編碼的字元。如果加上utf-8聲明,程式就不會報錯。

# -*- coding:utf-8 -*-

str = "你好"
print str

  雖然以上寫法不會報錯,但是輸出的卻是亂碼,為什麼呢?這就是下麵要講的內容。

 

encode和decode

講解編碼和解碼之前,先來講講Unicode和utf-8的關係,推薦這篇博客給大家。

可以這樣來理解:字元串是由字元構成,字元在電腦硬體中通過二進位形式存儲,這種二進位形式就是編碼。如果直接使用 “字元串↔️字元↔️二進位表示(編碼)” ,會增加不同類型編碼之間轉換的複雜性。所以引入了一個抽象層,“字元串↔️字元↔️與存儲無關的表示↔️二進位表示(編碼)” ,這樣,可以用一種與存儲無關的形式表示字元,不同的編碼之間轉換時可以先轉換到這個抽象層,然後再轉換為其他編碼形式。在這裡,unicode 就是 “與存儲無關的表示”,utf—8 就是 “二進位表示”。 python2中字元串有兩種表示形式,str和unicode。str可以理解為上面這段話中的二進位編碼格式,unicode可以理解為抽象層。encode是編碼,即從unicode格式到二進位的編碼格式如utf-8、gb2312等。decode是解碼,即從二進位編碼格式到unicode編碼格式。 下麵請看代碼:
# -*- coding:utf-8 -*-

str1 = "你好"
print type(str1)
str2 = str1.decode("utf-8")
print type(str2)

  str1是str類型, 通過decode轉為了unicode類型。

下麵看encode代碼:

# -*- coding:utf-8 -*-

str1 = u"你好"
print type(str1)
str2 = str1.encode("utf-8")
print type(str2)

  str1是unicode類型,通過encode轉為了str類型。

 

我們再回頭看最開始留下的問題,那段代碼為什麼會輸出亂碼呢。因為文件規定的編碼格式是utf-8,但是我們print是列印到控制台的,控制台無法顯示utf-8編碼格式的字元。所以我們要轉一下格式。

# -*- coding:utf-8 -*-

str = "你好"
str = str.decode("utf-8")
print str

  很多時候編碼解碼的時候需要加ignore參數才能正確轉換,例如.encode('utf-8', 'ignore')或.decode('utf-8', 'ignore'),大家自行斟酌吧。

 

chardet獲取編碼格式

有些時候我們是無法知道字元串是什麼編碼的,比如抓取網頁時,有些是utf-8的,有些是gb2312編碼的,那我們該怎麼獲取編碼格式並轉換為unicode呢。這裡就介紹到一個第三方庫chardet。使用方式大概如下:

# -*- coding: utf-8 -*-

import chardet

str = "xxxxx"
str_type = chardet.detect(str)
code = str_type['encoding']

  code即為str的編碼格式。但有些人反映該方法得到的編碼格式不准確,速度也慢。本人親測,速度確實一般,但是目前還沒遇到不准確的情況。大家可以斟酌使用,我這裡只是提供一個思路,如果誰那裡有更好的方式,可以告知小弟,不吝賜教才是。

 

import sys

reload(sys)

sys.setdefaultencoding('utf8')

之前也遇到過很莫名其妙的編碼錯誤,網上搜到這種方法能解決就糊裡糊塗的用上了,也不知是什麼原理。今天看到一篇不錯的博客,推薦給大家:http://blog.csdn.net/crazyhacking/article/details/39375535。以下內容引用自該篇文章:

Python 裡面的編碼和解碼也就是 unicode 和 str 這兩種形式的相互轉化。編碼是 unicode -> str,相反的,解碼就是 str -> unicode。剩下的問題就是確定何時需要進行編碼或者解碼了.關於文件開頭的"編碼指示",也就是 # -*- coding: -*- 這個語句。Python 預設腳本文件都是 UTF-8 編碼的,當文件中有非 UTF-8 編碼範圍內的字元的時候就要使用"編碼指示"來修正. 關於 sys.defaultencoding,這個在解碼沒有明確指明解碼方式的時候使用。比如我有如下代碼: 
#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
s = '中文'  # 註意這裡的 str 是 str 類型的,而不是 unicode 
s.encode('gb18030') 

這句代碼將 s 重新編碼為 gb18030 的格式,即進行 unicode -> str 的轉換。因為 s 本身就是 str 類型的,因此 Python 會自動的先將 s 解碼為 unicode ,然後再編碼成 gb18030。因為解碼是python自動進行的,我們沒有指明解碼方式,python 就會使用 sys.defaultencoding 指明的方式來解碼。很多情況下 sys.defaultencoding 是 ANSCII,如果 s 不是這個類型就會出錯。拿上面的情況來說,我的 sys.defaultencoding 是 anscii,而 s 的編碼方式和文件的編碼方式一致,是 utf8 的,所以出錯了: 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 
0: ordinal not in range(128) 
對於這種情況,我們有兩種方法來改正錯誤: 
一是明確的指示出 s 的編碼方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

s = '中文' 
s.decode('utf-8').encode('gb18030') 


二是更改 sys.defaultencoding 為文件的編碼方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
reload(sys) # Python2.5 初始化後會刪除 sys.setdefaultencoding 這個方法,我們需要重新載入 
sys.setdefaultencoding('utf-8') 

str = '中文' 
str.encode('gb18030')

   

看完之後,改成這樣

print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8') 
成功通過.

  但是這種方式用著就是彆扭,還是儘量自己來控制編碼,明確了編碼格式,自己寫著也踏實。

 

個人總結

實際編程過程中,最好能在代碼內統一編碼格式,比如統一為unicode,因為這樣就不用考慮編碼的問題了。到了顯示或輸出時再轉換為存儲類型(utf-8、GBK)。

 

以上為最近編寫python代碼的過程中遇到的一些問題及總結,如果有什麼不對的地方還請大家及時回覆交流,在此謝過。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Windows下安裝ruby先安裝ruby吧點擊安裝,額,咳咳什麼情況,好了 人是有國籍的,但知識無國界的是這個意思吧,選擇安裝語言選擇安裝目錄順便勾選上添加到環境變數吧安裝完成打開命令行,ruby -v查看下吧,安裝成功如何在Mac OS X上安裝 Ruby運行環境 對於新入門的開發者,如何安裝....
  • 轉至:http://blog.csdn.net/whycold/article/details/41119807RabbitMQ簡介 AMQP,即Advanced Message Queuing Protocol,高級消息隊列協議,是應用層協議的一個開放標準,為面向消息的中間件設計。消息中間件主要....
  • #coding:utf-8__author__ = 'similarface''''序列的排列組合'''def permute(list): ''' 序列的排列數: abc=abc,acb,bac,aca,cab,cba :param list: :return: ''...
  • 一、cookie 起源cookie 最早是網景公司的雇員 Lou Montulli 在1993年3月發明,後被 W3C 採納,目前 cookie 已經成為標準,所有的主流瀏覽器如 IE、Chrome、Firefox、Opera 等都支持。cookie 的誕生是由於 HTTP 協議的天生缺陷,HTTP...
  • 設置session用memcache來存儲方法I: 在 php.ini 中全局設置 session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211" 方法II: 某個目錄下的 .htaccess php_val.....
  • win/linux中的文件屬主獲取方法,寫了很多遍都記不住 - -, 還是記錄一下,i)win中通過apiGetNamedSecurityInfo 獲取到ower_sid, group_sid, 或者通過 getfilesecurity 獲取到文件的file_sid, 通過GetSecurityDe...
  • 一、下載jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html二、安裝JDk2.1、解壓jdk1.創建一個目錄ln0491@ln0491-virtual-machine:/$ su...
  • 購物車一、具體實現功能:1.用戶的註冊、登錄、充值、餘額查詢2.顯示商品列表、價格、庫存,顯示購物車內商品和數量3.對購物車內商品能進行減少二、具體流程圖三、代碼實現1.用到文件goods.txt1,apple,1500,1002,banana,2000,1003,orange,500,1004,p...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...