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)換行的符號替換成另一個符號"" (End of Sentence縮寫)。

"split()"完整的呼叫語法是split(str="", num=string.count(str))str是指定哪個符號是分隔符,預設值是使用空格符,空格符包括空格、換行(\n)、制表符(\t)等< num是分割次數,預設值是整個string的單字數量。我猜測因為split會把換行符號當作分隔符,但是文件可能會有連字號(-)跨行把長單字拆成兩行。所以需要把"\n"先換成"",避免python把長單字拆成兩個字。

如果不是python 3環境,會多一個.decode("utf-8"),意思是把f.read()轉碼成utf-8編碼,可能的原因是因為非pyhton 2環境可能會使用不是utf-8的編碼,所以要明確寫出來告訴直譯器。在split()執行完成之後會產生一個字符串列表(list of string)。

宏觀來說,function _read_words是輸入一個檔案路徑,輸出該檔案裡面所有的單字,以一個列表(list)來儲存。

[1] https://openhome.cc/Gossip/Python/WithAs.html

results matching ""

    No results matching ""