--- type: slide tags: sprout --- # FILE I/O, pickle, json, csv 2022 資訊之芽 北區py班 yjrubixcube --- ## 甚麼是I/O ---- I: input 輸入 O: output 輸出 今天要講的是檔案的I/O --- # 路徑path ---- 如果你在學校要找班上的1號 :male-student: :欸欸1號ㄩㄇ ---- 如果要找隔壁班的1號 :female-student:: (先跑去隔壁班)欸欸1號ㄩㄇ ---- 如果不想跑去隔壁班 可以用廣播 但是因為有很多班所以不能直接說1號ㄩㄇ :speaker:: x年y班的1號ㄩㄇ ---- 檔案路徑也是一樣 相對路徑vs絕對路徑 ---- ## 相對路徑 從你現在的資料夾開始算 ![](https://i.imgur.com/NZVqbQ5.png) 假設你現在在`homework`資料夾裡面 ```python= game.py ./game.py ../homework/game.py ../schoolwork/project.py ``` `.`: 從現在的資料夾開始 `..`: 從上一層資料夾開始 ---- ## 絕對路徑 從最上層資料夾開始 Windows `C:/Users/user_a/Documents/hello.py` Mac `/Users/user_a/Documents/hello.py` Linux `/media/hello.py` --- ## 開檔 ---- 語法 `open(路徑,模式)` ```python= f = open("./hello.txt", 'r') ``` |模式|說明| |-|-| |`r` |read 讀| |`w` |write 寫,如果檔案存在會覆蓋,不存在會建立| |`a` |append 寫在後面| |`x` | 建立並打開一個新檔案,可寫入| --- ## 讀檔 ---- ### 讀一行 ```python= f = open("hello.txt", "r") line1 = f.readline() print(line1, end='') line2 = f.readline() print(line2, end='') ``` ---- ### 讀幾個字元 讀14個字元 ```python= f = open("hello.txt", "r") s = f.read(14) print(s, end='') ``` 讀第一行的前14個字元,不會讀到第二行 ```python= f = open("hello.txt", "r") s = f.readline(14) print(s, end='') ``` ---- ### 讀整個檔案 `read()`不加長度 ```python= f = open("hello.txt", 'r') s = f.read() print(s, end='') ``` `readlines()`回傳一個list ```python= f = open("hello.txt", 'r') lines = f.readlines() for line in lines: print(line, end='') ``` --- ## 寫檔 ---- ```python= f = open("hello.txt", 'w') # awx f.write("Hello, world!\nThis is a new line!!") f.write("This is not a new line.") ``` `write`裡面放甚麼就寫什麼 不會自動幫你換行 ---- `print`大法 ```python= f = open("hello.txt", 'w') print("Hello, world!", file=f) f.close() ``` --- ## 關檔 ---- ```python= f = open("hello.txt", 'w') f.close() ``` ---- 為甚麼要關檔 1. 開著佔記憶體 2. 關檔之前不會真的寫入 3. 避免開超過上限個檔案 4. 會被笑 ---- 如果想要馬上寫怎麼辦 ```python= f = open("hello.txt", w) f.write("Hello, world!") f.flush() ``` --- ## 黑科技 ---- 這兩個是一樣的 ```python= with open("hello.txt", 'r') as f: print(f.read()) ``` ```python= f = open("hello.txt", 'r') print(f.read()) f.close() ``` ---- ### 好處 - 只有在`with`裡面檔案是開的 - 不需要自己寫`close` --- ## 練習時間 [8763](https://neoj.sprout.tw/problem/8763/) --- ## Pickle ![](https://i.imgur.com/MFjosxp.jpg) ---- 醃黃瓜可以用來保存蔬菜 pickle可以用來存Python的物件 ---- ```python= import pickle d = {1: 'a', 2: 'b', 3: 'c'} l = ['abc', 'def', 123] with open("pk_test", "wb") as f: pickle.dump(d, f) pickle.dump(l, f) with open("pk_test", "rb") as f: print(pickle.load(f)) print(pickle.load(f)) ``` `b`的意思是binary file --- ## json ---- JavaScript Object Notation 可讀性比較高的儲存方式 基本上就是list跟dict的組合 適合樹狀結構 ---- ### json :chestnut: ```json= { "book": [ { "date": "1989/06/04", "ver": 1 }, { "date": "2000/01/01", "ver": 2 } ] } ``` ---- ### dumps 跟 loads `dumps`: dict/list轉str `loads`: str轉dict/list ```python= import json data = { "book": [ { "date": "1989/06/04", "ver": 1 }, { "date": "2000/01/01", "ver": 2 } ] } s = json.dumps(data, indent=2) print(s) j = json.loads(s) print(j) ``` ---- ### dump跟load `dump`: dict/list轉str然後寫入檔案 `load`: 檔案轉dict/list ```python= import json with open("sample.json", 'r') as f: j = json.load(f) j['book'][1]["ver"] = 3 with open("changed.json", 'w') as c: json.dump(j, c) ``` ---- ### [JSON formatter](https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa) ---- ![](https://i.imgur.com/EHS7Tag.png) ---- ![](https://i.imgur.com/IEgGeMH.png) --- ## csv ---- comma separated value 顧名思義就是用逗點分隔的值 ---- ||math|science| |-|-|-| |Alice|100|99| |Bob|87|78| ```csv= ,"math","science" "Alice",100,99 "Bob",87,78 ``` ---- ### 讀csv ```python= import csv with open("sample.csv", 'r') as f: reader = csv.reader(f) for i in reader: print(i) ``` ``` ['name', 'math', 'science'] ['Alice', '100', '99'] ['Bob', '87', '78'] ``` ---- ### 寫csv 二維陣列版 ```python= import csv data = [("Alice",100,99), ("Bob",87,78)] field = ["name", "math", "science"] with open("sample.csv", 'w', newline='') as f: writer = csv.writer(f) writer.writerow(field) writer.writerows(data) ``` ```csv= name,math,science Alice,100,99 Bob,87,78 ``` ---- ### 寫csv dict版 ```python= import csv data = [ {"name": "Alice", "math": 100, "science": 99}, {"name": "Bob", "math": 87, "science": 78}] field = ["name", "math", "science"] with open("sample.csv", 'w', newline='') as f: writer = csv.DictWriter(f, fieldnames=field) writer.writeheader() writer.writerows(data) ``` ```csv= name,math,science Alice,100,99 Bob,87,78 ``` --- ## 延伸閱讀 - [google](https://google.com) - [pickle官網](https://docs.python.org/3/library/pickle.html) - [json官網](https://www.json.org/json-en.html) - [2021資芽](https://hackmd.io/@robert1003/BkjOrzb9L#/) - w3school