>[success] # Python -- 文件的讀寫
~~~
1.一個運行中的程序會存取放在隨機存取存儲器(RAM)上的數據。RAM 讀
取速度快,但 價格昂貴,需要持續供電,斷電后保存在上面的數據會自動消
失。磁盤速度比 RAM 慢, 但容量大、費用低廉并且多次插拔電源線仍可保
持數據。因此,計算機系統在數據存儲設 計中做出很大的努力來權衡磁盤和
RAM。程序員需要在非易失性介質(例如磁盤)上做 持久化存儲和檢索數
據。
2.因此整個讀寫操作相當于是在ram 執行的,使用的是ram內存條中的內存,
通俗的說是在一個文件 名下的字節流,把數據從一個文件讀入內存,然后從
內存寫入文件。
~~~
>[danger] ##### 常見的讀寫模式
~~~
1.了解讀寫的文件分兩種,一種是普通文本文件,一種是二進制文件(圖片,
音樂等),因此在python中,也分這兩種模式,t(或者省略)代表文本類
型; b 代表二進制文件。
2. 只讀(r, rb)
3. 只寫(w, wb)
4. 追加(a, ab)
5. r+讀寫
6. w+寫讀
7. a+寫讀(追加寫讀)
~~~
>[danger] ##### 使用open -- 進行讀寫操作
~~~
1.open(filename,mode,encoding)中常用的三個參數 ,第一個filename是文件
名稱,mode使用的讀寫模式,encoding 進行編碼解碼
2.在操作文件讀寫后需要關閉句柄,也就是close 操作
~~~
>[danger] ##### read -- (r,rb) 只讀模式
~~~
1.r是rt 模式的縮寫,是讀取文本類的,rb是讀取二進制類的例如圖片
2.使用 read() 函數一次讀入文件的所有內容。但在 讀入文件時要格外注意,
1GB 的文件會用到相同大小的內存。因此會有更好的優化方案見案例
3.rb讀取出來的數據是bytes類型, 在rb模式下. 不能選擇encoding字符集.
4.read(n) 讀取n個字符. 需要注意的是. 如果再次讀取. 那么會在當前位置繼
續去讀?而不 是從頭讀, 如果使?用的是rb模式. 則讀取出來的是n個字節
~~~
* 案例 普通的讀寫案例
~~~
f = open('../file/test', 'r', encoding='utf-8')
s = f.read() #read 是當前對象的一個方法,讀出這個對象內的內容
print(s)
~~~
* 優化 讀多少拿多少
~~~
f = open('../file/test', 'r', encoding='utf-8')
content = '' # 記錄所有內容
chunk = 50 # 一次讀取多少個字符
while True:
s = f.read(chunk)
if not s:
break
content += s
print(content)
~~~
>[danger] ##### write -- (w, wb) 寫模式存在則刪除
~~~
1.寫的時候注意. 如果沒有?文件. 則會創建?文件, 如果?文件存在. 則將原
件中原來的內容刪除, 再 寫入新內容
2.在寫的時候注意兩個好習慣一個是刷新,一個是關閉 f.flush() /f.close()
3.這是只寫模式,不能進行讀的操作
~~~
* 寫入案例 -- write篇章
~~~
content = '寫入的新的內容'
f = open('../file/test', 'w', encoding='utf-8')
f.write(content)
f.flush()
f.close()
~~~
* 寫入案例 -- 萬能print
~~~
# print 因為自帶換行符,因此在使用的時候要考慮去掉默認的換行符
content = '寫入的新的內容'
f = open('../file/test', 'w', encoding='utf-8')
print(content, file=f, sep='', end='')
f.close()
~~~
* 優化 寫多少存多少
~~~
content = '寫入的新的內容'
offset = 0
chunk = 2 # 一次寫入多少
f = open('../file/test', 'w', encoding='utf-8')
while len(content) > offset:
f.write(content[offset:offset+chunk])
offset += chunk
f.close()
~~~
* 二進制寫入
wb模式下. 可以不指定打開?文件的編碼. 但是在寫?文件的時候必須將字符串串轉化成utf-8的 bytes數據
~~~
f = open("?小娃娃", mode="wb")
f.write("?金金?毛獅王".encode("utf-8"))
f.flush()
f.close()
~~~
>[danger] ##### 追加(a, ab) -- 在末尾追加
~~~
1.在追加模式下. 我們寫入的內容會追加在?文件的結尾,必須文件存在
~~~
* 案例
~~~
f = open('../file/test', 'a', encoding='utf-8')
f.write("追加內容")
f.flush()
f.close()
~~~
>[danger] ##### r+ /r+b -- 讀寫模式
~~~
1.對于讀寫模式. 必須是先讀. 因為默認光標是在開頭的. 準備讀取的. 當讀完
了之后再進?行行 寫入. 使?頻率最?高的模式就是r+
2..在沒有任何操作之前進行寫. 在開頭寫
3. 如果讀取了一些內容. 再寫, 寫入的是最后,也就是說read(1)執行了雖然
是讀一個字符,但追加的內容也會在整個文章最后
~~~
* 必須是先讀取. 然后再寫入
~~~
f = open("?小娃娃", mode="r+", encoding="utf-8")
content = f.read()
f.write("麻花藤的最愛")
print(content)
f.flush()
f.close()
~~~
* 如果先寫后讀就會出現,追加的內容在,開頭而不是在結尾,錯誤示范如下:
~~~
f = open("?小娃娃", mode="r+", encoding="utf-8")
f.write("哈哈") content = f.read()
print(content)
f.flush()
f.close()
結果: 將開頭的內容改寫成了了"哈哈", 然后讀取的內容是后?面的內容.
~~~
>[danger] ##### readline() / readlines() -- 以行為單位讀
~~~
1.readline() 和 .readlines() 之間的差異是后者一次讀取整個文件
2.readline() 每次只讀取一行,通常比 .readlines() 慢得多。僅當沒有足夠內存可以一次讀取整個文件時,才應該使用 .readline()。
~~~
* 案例 -- 直接常用寫法
~~~
f = open("吃的", mode="r", encoding="utf-8")
for line in f: # 每次讀取一行. 賦值給前面的line變量
print(line)
f.close()
~~~
* 性能 讀法
~~~
poem = ''
fin = open('relativity', 'rt' )
while True:
line = fin.readline()
if not line:
break
poem += line
fin.close()
~~~
>[danger] ##### w+/w+b -- 寫讀
~~~
1. 先將所有的內容清空. 然后寫入. 最后讀取. 但是讀取的內容是空的, 不常?
2. 一開始讀取不到數據. 然后寫的時候再將原來的內容清空,不常用
~~~
* 案例
~~~
f = open("?小娃娃", mode="w+", encoding="utf-8")
f.write("哈哈")
content = f.read()
print(content)
f.flush()
f.close()
~~~
>[danger] ##### 追加讀(a+)
~~~
1.啥用沒有,a+模式下, 不論先讀還是后讀. 都是讀取不到數據的.
~~~
~~~
f = open('../file/test', 'a+', encoding='utf-8')
f.write("追加內容")
s = f.read()
print(s)
~~~
>[danger] ##### seek(n) -- 光標移動
~~~
1. seek(n) 光標移動到n位置, 注意, 移動的單位是byte. 所以如果是UTF-8的
中?文部分要 是3的倍數. 三個字節構成一個字符
2. 移動到開頭: seek(0),移動到結尾: seek(0,2) seek的第?二個參數表
?示的是從哪個位置進?行行偏移, 默認是0, 表 ?示開頭, 1表?示當前位
置, 2表?示結尾
~~~
* 案例
~~~
f = open("?小娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光標移動到開頭
content = f.read() # 讀取內容, 此時光標移動到結尾
print(content) f.seek(0) # 再次將光標移動到開頭
f.seek(0, 2) # 將光標移動到結尾
content2 = f.read() # 讀取內容. 什什么都沒有
print(content2) f.seek(0) # 移動到開頭
f.write("張國榮") # 寫?入信息. 此時光標在9 中?文3 * 3個 = 9
f.flush()
f.close()
~~~
>[danger] ##### 使用with自動關閉文件
~~~
1.如果你忘記關閉已經打開的一個文件, 在該文件對象不再被引用之后
Python 會關掉此文 件。這也就意味著在一個函數中打開文件,沒有及時關
閉它,但是在函數結束時會被關 掉。然而你可能會在一直運行中的函數或
者程序的主要部分打開一個文件,應該強制剩下 的所有寫操作完成后再關
閉文件。
Python 的上下文管理器(context manager)會清理一些資源,例如打開的文件。它的形式 為 with expression as variable:
with open('relativity', 'wt') as fout: ... fout.write(poem) ...
完成上下文管理器的代碼后,文件會被自動關閉。
~~~
>[danger] ##### 修改文件內容
* 先讀在寫寫的文件,刪除讀的,重命名寫的
~~~
import os
with open("吃的", mode="r", encoding="utf-8") as f1, \
open("吃的_副本", mode="w", encoding="utf-8") as f2:
for line in f1:
s = line.replace("菜", "肉")
f2.write(s)
os.remove("吃的") # 刪除文件
os.rename("吃的_副本", "吃的") # 重命名文件
~~~
>[danger] ##### 整合模式
~~~
1.使用with
2.使用for 循環
~~~
- PYTHON-- 基礎
- Python -- 變量、常量、注解
- 算數\比較\賦值\邏輯運算符
- Python -- input 控制臺用戶輸入
- Python -- 流程控制/循環語句
- Python -- 切片
- Python -- 數據類型
- 基礎數據類型
- int -- 數字類型
- str -- 字符類型
- bool -- 布爾類型
- list -- 列表
- type -- 元祖
- dict -- 字典
- set -- 集合
- Python -- 深淺copy
- Python -- 文件的讀寫
- Python -- 函數
- 函數 -- 做參數使用
- 函數 -- 閉包
- 函數 -- 生成器
- 函數 -- 列表推導式
- 案例
- 基礎案例一
- 基礎案例二
- 基礎案例三
- COOKBOOK
- LIST、STR、DICT、TUPLE
- LIST - 列表方法總結
- 一、序列拆分成單獨變量
- 二、* 妙用
- 三、deque- 雙向隊列
- 四、求找到最大或最小的N個元素
- 4.1 heapq-- 簡單使用
- 五、去重并保持列表順序不變
- 六、切片slice
- 七、counter 統計序列中元素次數
- 八、itemgetter 列表套著字典排序
- 九、處理大量的列表數據
- 十、隨機事件處理列表
- DICT - 字典的總結方法
- 一、defaultdict 解決 KeyError
- 二、OrdereDict有序字典
- 三、zip 和 max/min 比較
- IDCT和LIST- 推導式
- 一、LIST 推導式
- 二、字典推到式
- TUPLE-元組
- 一、命名元組
- STR-字符串
- 一、常見的字符串方法
- 二、字符串拆分
- 三、字符串的位置匹配
- 四、字符串替換
- 五、正則大小寫/換行匹配
- 六、對字節類型處理
- 數字、日期、時間處理
- 一、數字的處理
- 二、時間換算
- 2.1 時間運算
- 2.2計算某一時刻上周幾的日期
- 2.2對時間轉換格式優化
- 迭代器和生成器
- 一、iter 迭代器 使用案例
- 二、生成器 yeild
- 三、構建一個反向迭代方法
- 四、實現反正函數構造
- 五、迭代對象切片/跳過元素
- 六、迭代出所有的組合排列
- 七、索引-值迭代序列化
- 八、zip 同時迭代多個序列
- 九、同時循環多個可迭代對象
- 十、yield from 遞歸案例
- 十一、合并序列,并按順序輸出
- 十二、使用 iter 替代 while True
- 操作文件
- 一、處理文件路徑
- 二、檢測文件/獲取文件信息
- 函數
- 一、函數基本案例使用
- 二、匿名函數
- 三、回調函數
- 四、閉包實現一個單個方法類
- 五、函數嵌套回調函數
- 類與對象
- 一、str/repr--讓類字符串表示
- 二、format -- 格式化類的內容
- 三、with -- 上下文管理類
- 四、創建節省內存的類
- 五、將類里面方法變成屬性
- 六、調用父類方法
- 七、擴展子類中的屬性
- 八、創建新的類或者實類屬性
- 九、簡化數據結果,簡化init
- 十、python 接口寫法
- 十一、通過類屬性創建委托訪問
- 十二、__new__重新初始化init
- 十三、通過字符串調用類
- 元編程
- 一、裝飾器
- 1.1 去掉裝飾器修飾
- 1.2 可接受參數裝飾器
- 1.3利用裝飾器對函數參數類型檢查
- 1.4編寫類裝飾器
- 1.5為類方法和靜態方法加裝飾器
- 1.6通過裝飾器給裝飾函數加參數
- 線程和進程