# 練習15.讀文件
你已經學過`raw_input`和`argv`,這些是你開始學習讀取文件的必備基礎。你可能需要多多實驗才能明白它的工作原理,所以你要細心做練習,并且仔細檢查結果。處理文件需要非常仔細,否則,你可能會把有用的文件弄壞或者清空。導致前功盡棄。
這節練習涉及到寫兩個文件。一個正常的 ex15.py 文件,另外一個是 ex15_sample.txt,第二個文件并不是腳本,而是供你的腳本讀取的文本文件。以下是后者的內容:
~~~
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
~~~
我們要做的是用我們的腳本“打開(open)”這個文件,然后打印出來。然而把文件名`ex15_sample.txt`寫死在代碼中并不是一個好主意,這些信息應該是用戶輸入的才對。如果我們碰到其他文件要處理,寫死的文件名就會給你帶來麻煩了。我們的解決方案是使用`argv`和`raw_input`來從用戶獲取信息,從而知道哪些文件該被處理。
~~~
from sys import argv
script, filename = argv
txt = open(filename)
print "Here's your file %r:" % filename
print txt.read()
print "Type the filename again:"
file_again = raw_input("> ")
txt_again = open(file_again)
print txt_again.read()
~~~
這個腳本中有一些新奇的玩意,我們來快速地過一遍:
代碼的 1-3 行使用`argv`來獲取文件名,這個你應該已經熟悉了。接下來第 5 行我們看到`open`這個新命令。現在請在命令行運行`pydoc open` 來讀讀它的說明。你可以看到它和你自己的腳本、或者`raw_input`命令類似,它會接受一個參數,并且返回一個值,你可以將這個值賦予一個變量。這就是你打開文件的過程。
第 7 行我們打印了一小行信息,但在第 8 行我們看到了新奇的東西。我們在 `txt` 上調用了一個函數。你從`open`獲得了一個文件,文件本身也支持一些命令。它接受命令的方式是使用句點 `.` (英文稱作 dot 或者 period),緊跟著你的命令,然后是類似 `open` 和 `raw_input` 一樣的參數。不同點是:當你執行`txt.read`時,你的意思其實是:“嘿 txt!執行你的 read 命令,無需任何參數!”
腳本剩下的部分基本差不多,不過我就把剩下的分析作為附加題留給你自己了。
## 你看到的結果
我創建了一個名字叫做`ex15_sample.txt`的文件,然后執行我的腳本:
~~~
$ python ex15.py ex15_sample.txt
Here's your file 'ex15_sample.txt':
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
Type the filename again:
> ex15_sample.txt
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
~~~
## 附加題
這節的難度跨越有點大,所以你要盡量做好這節加分習題,然后再繼續后面的章節。
> 1. 在每一行的上面加上注釋。
> 1. 如果你不確定答案,就問別人,或者上網搜索。大部分時候,只要搜索 “python” 加上你要搜的東西就能得到你要的答案。比如搜索一下“python open”。
> 1. 我使用了“命令”這個詞,不過實際上它們的名字是“函數(function)”和“方法(method)。上網搜索一下這兩者的意義和區別。看不明白也沒關系,這本書后面也會講到這些。
> 1. 刪掉 10-15 行使用到`raw_input`的部分,再運行一遍腳本。
> 1. 只用`raw_input`寫這個腳本,想想哪種得到文件名稱的方法更好?為什么?
> 1. 運行 python 在命令行下使用 open 打開一個文件,這種 open 和 read 的方法也值得你一學。
> 1. 讓你的腳本對 `txt`和`txt_again`兩個變量執行一下 `close()`,處理完文件后你需要將其關閉,這是很重要的一點。
## 常見問題
### Q:`txt = open(filename)`返回的是文件的文本內容嗎?
> 不是的。它的返回值我們稱為“文件對象”。你可以把文件想象成19世紀50年代的大型計算機上的老舊的磁帶驅動器, 或者是像現在的DVD播放器,你可以在他們內部走動,然后閱讀他們。但是文件對象并不是文件的文本內容一樣就好像DVD播放器也不是一個DVD視頻.
### Q:我不能按照你在附加題7中說的那樣在命令行輸入代碼
> 首先,在命令行里輸入`python`并回車,現在你已經進入了一個python解析器。接下來你就可以輸入一系列的代碼,python會一一執行你的代碼。最后別忘了輸入`quit()`并回車退出python。
### Q:當我打開同一個文件兩次的時候,為什么不會報錯?
> Python不會限制你只能打開一個文件一次,有時這是必要的。
### Q:`from sys import argv` 這句是什么意思?
> 目前來說,你可以認為`sys`是一個包,這句代碼的意思是從`sys`的包中引入`argv`功能模塊。
### Q: 我把文件的名字放進腳本中,`ex15_sample.txt = argv`,卻沒有生效。
> 你不能這么寫,請按照我的示例寫代碼,并像我一樣在命令行里運行腳本。
- 序言
- 前言
- 簡介
- 0:安裝和準備
- 1:第一個程序
- 2:注釋和“#”井號
- 3:數字和數學計算
- 4:變量和命名
- 5:更多的變量和打印
- 6:字符串和文本
- 7:更多的打印(輸出)
- 8:打印, 打印
- 9:打印, 打印, 打印
- 10:那是什么?
- 11:提問
- 12:提示別人
- 13:參數, 解包, 變量
- 14:提示和傳遞
- 15:讀文件
- 16:讀寫文件
- 17:更多文件操作
- 18:命名, 變量, 代碼, 函數
- 19:函數和變量
- 20:函數和文件
- 21:函數的返回值
- 22:到目前為止你學到了什么?
- 23:閱讀代碼
- 24:更多的練習
- 25:更多更多的練習
- 26:恭喜你,可以進行一次考試了
- 27:記住邏輯
- 28:布爾表達式
- 29:IF 語句
- 30:Else 和 If
- 31:做出決定
- 32:循環和列表
- 33:while循環
- 34:訪問列表元素
- 35:分支和函數
- 36:設計和調試
- 37:復習符號
- 38:列表操作
- 39:字典,可愛的字典
- 40:模塊, 類和對象
- 41:學會說面向對象
- 42:對象、類、以及從屬關系
- 43:基本的面向對象的分析和設計
- 44:繼承Vs.包含
- 45:你來制作一個游戲
- 46:項目骨架
- 47:自動化測試
- 48:更復雜的用戶輸入
- 49:寫代碼語句
- 50:你的第一個網站
- 51:從瀏覽器獲取輸入
- 52:開始你的web游戲
- 來自老程序員的建議
- 下一步
- 附錄A:命令行教程
- 簡介
- 安裝和準備
- 路徑, 文件夾, 名錄 (pwd)
- 如果你迷路了
- 創建一個路徑 (mkdir)
- 改變當前路徑 (cd)
- 列出當前路徑 (ls)
- 刪除路徑 (rmdir)
- 目錄切換(pushd, popd)
- 生成一個空文件(Touch, New-Item)
- 復制文件 (cp)
- 移動文件 (mv)
- 查看文件 (less, MORE)
- 輸出文件 (cat)
- 刪除文件 (rm)
- 退出命令行 (exit)
- 下一步