Python 3 Tutorial 第二堂(1)Unicode 支援、基本I/O
文章推薦指數: 80 %
filename = input('檔名:') file = open(filename, 'r', encoding='UTF-8') ... 實際上對於Python 來說,讀取檔案最好的方式,就是不要去 read 它,這是什麼意思?
回PythonTutorial
在第一堂下課之前,我們完成了練習1:哈囉!世界!,那麼那些程式碼中做了什麼?為了方便,把範例程式碼再貼過來一下:
filename=input('檔名:')
file=open(filename,'r',encoding='UTF-8')
content=file.read()
file.close()
print(content)
print(content.encode('UTF-8'))#這是什麼?
print(content.encode('UTF-8').decode('UTF-8'))#這是什麼?
原始碼檔案的編碼
首先,程式一開始使用input函式指定提示訊息,這會讓程式停下來等待使用者的輸入。
在提示訊息的部份使用了中文,在Ubuntu中這沒有問題,然而,若你試著在Windows環境中進行這個課程,第一個練習可能就會遇上問題:
這是因為Python3.x中,python直譯器預期的.py編碼,預設是UTF-8,而在Ubuntu15.10中,預設採用的文字編碼也是UTF-8,這時在.py檔案中撰寫中文,並不會有問題發生,然而,你知道在Windows中,使用記事本編輯文字檔案時,預設的文字編碼是什麼嗎?
有趣的是,有時我上課會問學員一個問題:「你用的原始碼文字編碼是什麼?」很多學員答不出來,很多人不知道自己作業系統中開個純文字檔編碼是什麼,不知道在整合開發環境(IntegratedDevelopmentEnvironment,IDE)中開個原始碼編碼是什麼,當然也就不知道為什麼把A專案的原始碼放到B專案中程式碼會出現亂碼。
如果你連UTF-8是什麼都不知道,那建議你看看我寫的〈亂碼1/2〉中這幾篇文件:
哪來的純文字檔?
Unicode與UTF
UTF-8
在Windows中使用記事本編輯文字檔案,預設的編碼是MS950,在Python3.x中,若.py檔案的編碼若不是UTF-8,必須在檔案的一開頭作編碼宣告(Encodingdeclaration):
編碼宣告是個魔法註解(Magiccomment),在上頭的例子中,#coding=MS950告訴Python直譯器,這個原始碼檔案是以MS950來編碼,如此就能正確地讀取.py檔案。
Python的Unicode支援
Python3.x中,文字是str型態的實例,不過str代表的是Unicode,下面這個程式在Python3.x中執行的話:
text='測試'
print(type(text))#顯示"
例如在Python2.x中,以下的程式會顯示6,即使'測試'是兩個字元:
#coding=UTF-8
text='測試'
printlen(text)#顯示6
這是因為'測試'這兩個字元,使用UTF-8編碼的話,會使用六個位元組,在Python2.x中,len函式實際上是計算位元組序列的長度,而不是字元長度。
在Python2.x中,如果想要用Unicode來代表文字,也就是想要用unicode型態來封裝文字,可以使用Unicode字面常量(Unicodeliteral)來表示,也就是在文字前置一個u符號。
例如:
#coding=UTF-8
text=u'測試'
printtype(text)#顯示"
為了讓Python3.x與2.x之間有更好的相容性,在Python3.5中,也可以使用u明確指定是一個str實例(記得,Python3.x中是代表Unicode),而使用b的話,表示是一個bytes實例,也就是一個位元組序列。
底下顯示了Python3.5與Python2.7的文字編碼差異:
在Python3.x中,如果想取得文字實際編碼後的位元組序列,可以使用encode方法指定編碼,這也會傳回一個bytes實例,如果有個bytes實例,可以使用decode指定編碼,傳回代表Unicode的str實例。
例如下圖是在Python3.x互動交談環境中的測試實例:
如果想知道更多Python中有關文字編碼的細節,可以再參考〈Python的編碼〉這篇文件。
基本I/O
接下來看看有關基本I/O的部份,你可以使用open函式來開啟檔案,開啟時指定存取模式,'r'表示讀取,'w'表示寫入,由於在Ubuntu中,預設的文字編碼是UTF-8,若你讀取的檔案中含有中文,最好是指定encoding參數,若不指定的話,就看系統是什麼編碼了,具體來說,就是以locale.getpreferredencoding(False)的傳回結果作為讀取時的編碼。
open函式會傳回_io.TextIOWrapper實例,使用read方法可以讀取檔案內容,以str型態傳回,以下是個實際的讀取程式範例:
importsys
file=open(sys.argv[1],'r')
content=file.read()
file.close()
print(content)
程式第一行匯入(import)了sys模組,sys.argv是個list,其中儲存了執行程式時的命令列引數(Commandlinearguments),索引0固定都是執行時的模組名稱,而後是跟隨著的引數,例如執行python3.5hello.pyonetwothree時,sys.argv[0]就會是'hello.py',其餘索引則是'one'、'two'、'three'。
print()在Python3.x中是個函式,用來顯示指定的資料。
不使用檔案時,記得使用close關閉檔案。
類似地,一個寫入檔案的程式範例如下,write方法會將文字的位元組序列寫入至檔案中:
importsys
file=open(sys.argv[1],'w')
file.write('test')
file.close()
如果要逐行讀取檔案呢?可以使用open傳回實例上的readline方法,例如逐行讀取一個文字檔案的所有內容,可以在while迴圈中進行:
importsys
file=open(sys.argv[1],'r')
whileTrue:
line=file.readline()
ifnotline:break
print(line,end='')
file.close()
如果讀不到東西了,那readline會傳回'',在if判斷式中,''會被視為False。
while後加上:表示區塊開始,Python中使用縮排來決定區塊範圍。
注意!你可以自行決定縮排字元,但是Python中縮排要一致,如果縮排想使用Tab字元,那所有原始碼就都要使用Tab字元縮排,如果要使用四個空白字元,那所有原始碼就得是四個空白字元來縮排,強制統一縮排,是Python的特色,也是Python的文化。
print()函式顯示完指定的文字後,預設會加上換行字元,若想指定其他字元,可以在end參數上指定,在上例中,加上了end='',也就不會換行了。
可以使用readlines方法一次讀取所有檔案內容,這會傳回list,每個索引處代表一行內容,一個程式範例是這樣的:
importsys
file=open(sys.argv[1],'r')
forlineinfile.readlines():
print(line,end='')
file.close()
forin語法可作用在list上,逐一取出list中的元素並指定給變數,對於forlineinfile.readlines()是這樣閱讀的:對於file.readlines()傳回的list中每個元素,將之指定給line。
實際上對於Python來說,讀取檔案最好的方式,就是不要去read它,這是什麼意思?是這樣的…
importsys
forlineinopen(sys.argv[1],'r'):
print(line,end='')
這是Python的風格,也是Python的文化,這樣的寫法好處就是增加了可讀性,你不用自行使用close關閉檔案,在open傳回的實例被回收後,檔案就會關閉,forlineinopen(sys.argv[1],'r')是這樣閱讀的:對於開啟檔案的每一行。
除了可讀性外,這個語法還能讓讀取更有效率,不過現階段你不用管這些事,只要當這語法背後施了些魔法就好。
延伸文章資訊
- 1Day28-text-binary-encoding - iT 邦幫忙
UTF-8就是一種以8位元為單元對Unicode進行編碼的方式,針對不同範圍的Unicode所使用的位元組長度是可變動的,ASCII只要使用1個位元組而中文需要3個位元組。 UTF-8沒有Byt...
- 2Day27 Python 基礎- 字符轉編碼操作 - iT 邦幫忙
coding:utf-8 -*- import sys print(sys.getdefaultencoding()) # 打印出目前系統字符編碼s = '你好' s_to_unicode = ...
- 3UTF-8 - 维基百科,自由的百科全书
- 4Python 3 Tutorial 第二堂(1)Unicode 支援、基本I/O
filename = input('檔名:') file = open(filename, 'r', encoding='UTF-8') ... 實際上對於Python 來說,讀取檔案最好的方式...
- 5你的原始碼是什麼編碼? - OpenHome.cc
如果在正體中文Windows 中開一個純文字檔案,用「記事本」編輯的話,應該是用MS950 來處理原始碼中字元的儲存,現在許多Linux 系統,預設使用UTF-8 編碼,所以在 ...