1 Py3 = sys.version_info[0] == 3
2
3 def _read_words(filename):
4 with tf.gfile.GFile(filename, "r") as f:
5 if Py3:
6 return f.read().replace("\n", "<eos>").split()
7 else:
8 return f.read().decode("utf-8").replace("\n", "<eos>").split()
Figure 1: Flowchart of hidden function _read_words.py
行1是使用sys的sys.version_info
property,來確認環境是python3[3],sys.version_info
提供一組tuple(major, minor,micro,releaselevel,serial)來表示當前Python的版本。
因為"=="運算元的優先序高於"=",所以會先執行sys.version_info[0] == 3
,得到一個boolean值,再把它assign到Py3。
行3是定義_read_words
,輸入一個參數filename
。
行4是使用with ... as ...
來開啟filename檔案[1]。 tf.gfile.GFile
是tensorflow的fileIO module,輸入filename並且"r"
指定該檔案是唯讀文字檔模式。
被打開的檔案都將以f
作稱。
如果環境是Python 3,就return f.read().replace("\n","<eos>").split()
,如果不是Python 3 則return f.read().decode("utf-8").replace("\n", "<eos>").split()
。為了更瞭解首先我們先來解釋dot語法,以f.read().replace("\n","<eos>").split()
為例,如果沒有括號指定,python會由左向右逐個dot處理,也就等效:
A = f.read()
B = A.replace("\n","<eos>")
return B.split()
先執行f.read()產生一個object A後,執行物件A的replace("\n","<eos>")
method ,又產生一個新物件B,最後執行物件B的split()
method,得到我們的output。這樣的寫法可以讓程式碼變得簡潔而且不用產生多餘的中間物件A,B,是python滿常見的語法。
f.read()
是把整個檔案的內容讀入。
replace("\n","<eos>")
是把原來文件裡“\n"(newline)換行的符號替換成另一個符號"
"split()"完整的呼叫語法是split(str="", num=string.count(str))
,str
是指定哪個符號是分隔符,預設值是使用空格符,空格符包括空格、換行(\n)、制表符(\t)等<
num
是分割次數,預設值是整個string的單字數量。我猜測因為split會把換行符號當作分隔符,但是文件可能會有連字號(-)跨行把長單字拆成兩行。所以需要把"\n"先換成"
如果不是python 3環境,會多一個.decode("utf-8")
,意思是把f.read()
轉碼成utf-8編碼,可能的原因是因為非pyhton 2環境可能會使用不是utf-8的編碼,所以要明確寫出來告訴直譯器。在split()
執行完成之後會產生一個字符串列表(list of string)。
宏觀來說,function _read_words
是輸入一個檔案路徑,輸出該檔案裡面所有的單字,以一個列表(list)來儲存。