讀寫文件
-
常規(guī)寫法
f = None try: # 標示符'r'表示讀 f = open("./mysql.java", "r") # 一次性讀取文件全部 print(f.read()) finally: if f: f.close()
-
簡潔寫法
with open("./mysql.java", "r") as i: # print(i.read()) # 如果不能確定文件大小,防止內存被爆,可反復調用read(size)方法,每次最多讀取size個字節(jié)的內容 # print(i.read(6)) # 讀取一行 readline() # print(i.readline()) # 調用readlines()一次讀取所有內容并按行返回list,讀取配置文件最方便 lines = i.readlines() print(lines) for line in lines: # 把末尾的'\n'刪掉 strip用來刪除首尾的空格 print(line.strip())
-
讀二進制文件
-
讀取二進制文件修噪,比如圖片、視頻肖爵,用'rb'模式打開文件即可
with open("./down.jpg", "rb") as t: print(t.read()) # b'\xff\xd8\xff\xe0\... 十六進制表示的字節(jié)
-
open函數還可傳入encoding參數,用來指定按什么編碼來打開文件冲簿;open函數還可傳入errors參數涣旨,表示如果遇到編碼錯誤后如何處理氏仗。最簡單的方式是直接忽略
with open("./gbk.txt", "r", encoding="gbk", errors="ignore") as g: print(g.read())
-
寫文件
with open("./write.txt", "w") as w: w.write("Hello Python")
-
StringIO和BytesIO
StringIO在內存中讀寫str围辙;BytesIO在內存中讀寫bytes
from io import StringIO, BytesIO
f = StringIO()
# 把str寫入StringIO
r = f.write("Hello")
f.write(" ")
f.write("World!")
# 獲取寫入后的值
print(f.getvalue()) # Hello World!
s = StringIO("Hello\nPython")
while True:
line = s.readline()
if line == "":
break
print(line.strip()) # Hello \n Python
# 在內存中讀寫bytes
b = BytesIO()
# 將bytes寫入BytesIO中
b.write("中文".encode("utf-8"))
print(b.getvalue()) # b'\xe4\xb8\xad\xe6\x96\x87'
# 讀取BytesIO中的bytes
b2 = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(b2.read()) # b'\xe4\xb8\xad\xe6\x96\x87'
操作文件和目錄
import os
# 操作系統類型
print(os.name)
# 獲取詳細的系統信息
print(os.uname())
# 獲取操作系統中定義的環(huán)境變量
print(os.environ)
# 查看當前目錄的絕對路徑
print(os.path.abspath(".")) # /Users/BlainPeng/Desktop/1/Python
# 通過join函數把把整個要創(chuàng)建的新目錄的地址拼接出來
# os.path.join("../", "testDir")
# 然后創(chuàng)建這個目錄
# os.mkdir("../testDir")
# 刪除這個目錄
# os.rmdir("../testDir")
# 拆分路徑
print(os.path.split(os.path.abspath(".") + "/s1.py")) # ('/Users/BlainPeng/Desktop/1/Python', 's1.py')
# 獲取文件擴展名
print(os.path.splitext(os.path.abspath(".") + "/s1.py")) # ('/Users/BlainPeng/Desktop/1/Python/s1', '.py')
# 給文件重新命名
# os.rename("test.txt", "test.py")
# 刪掉文件
# os.remove("test.java")
# 列出當前目錄下的所有目錄
print(list(x for x in os.listdir(".") if os.path.isdir(x))) # ['.idea', 'q1']
# 列出當前目錄下所有的.py文件
print(list(x for x in os.listdir(".") if os.path.isfile(x) and os.path.splitext(x)[1] == ".py")) # ['1.py', '2.py', '3.py', '4.py', '5.py', '6.py']
序列化(pickling)與反序列化(unpickling)
把變量從內存中變成可存儲或傳輸的過程叫做序列化我碟;反過來,把變量內容從序列化的對象重新讀到內存里稱之為反序列化
import pickle
d = dict(name="Tom", age=18, score=90)
print(d) # {'score': 90, 'name': 'Tom', 'age': 18}
# 把任意對象序列化成一個bytes,接著就可以把這個bytes寫入文件了
res = pickle.dumps(d)
print(res) # b'\x80\x03}q\x00(X\x05\x00\x00\x00scoreq...
# 將一個bytes反序列化成對象
src = pickle.loads(res)
print(src) # {'score': 90, 'name': 'Tom', 'age': 18}
# 把對象序列化后直接寫入一個file-like object
f = open("dump.java", "wb")
pickle.dump(d, f)
f.close()
# 從一個file-like Object中直接反序列化出對象
r = open("dump.java", "rb")
print(pickle.load(r)) # {'score': 90, 'name': 'Tom', 'age': 18}
r.close()
此種序列化與反序列化只能用于Python姚建,對于其它語言并不能兼容
Json
如果我們要在不同的編程語言之間傳遞對象矫俺,就必須把對象序列化為標準格式,比如XML掸冤,但更好的方法是序列化為JSON厘托,因為JSON表示出來就是一個字符串,可以被所有語言讀取稿湿,也可以方便地存儲到磁盤或者通過網絡傳輸
import json
d2 = dict(姓名="Jim", 年齡=18, 分數=95)
# Python對象轉化為JSON
res2 = json.dumps(d2, ensure_ascii=False)
print(res2) # {"分數": 95, "姓名": "Jim", "年齡": 18}
# 把JSON反序列化為Python對象
src2 = json.loads(res2)
print(type(src2)) # <class 'dict'>
print(src2) # {'分數': 95, '姓名': 'Jim', '年齡': 18}
with open("dump.json", "w", encoding="utf-8") as w:
# 直接把JSON寫入一個file-like Object
json.dump(d2, w, ensure_ascii=False)
with open("dump.json", "r", encoding="utf-8") as r:
# 直接從file-like Object中讀取字符串并反序列化
print(json.load(r)) # {'分數': 95, '姓名': 'Jim', '年齡': 18}
任意類轉Json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def student2dict(std):
return {
"name": std.name,
"age": std.age,
"score": std.score
}
def dict2student(d):
return Student(d["name"], d["age"], d["score"])
s = Student("吉姆", 18, 50)
# 把任意一個類對象序列化成Json
# 可選參數default就是把任意一個對象變成一個可序列為JSON的對象,需要自己寫轉換函數
res = json.dumps(s, ensure_ascii=False, default=student2dict)
print(res) # {"name": "吉姆", "age": 18, "score": 50}
# 簡單寫法: 把任意類的實例變?yōu)閐ict
# 通常class的實例都有一個__dict__屬性铅匹,它就是一個dict,用來存儲實例變量缎罢。也有少數例外伊群,比如定義了__slots__的class
print(json.dumps(s, ensure_ascii=False, default=lambda obj: obj.__dict__)) # {"score": 50, "name": "吉姆", "age": 18}
# 把Json轉化成類對象
json_str = r'{"name": "Mary","age": 18,"score": 95}'
print(json.loads(json_str, object_hook=dict2student)) # <__main__.Student object at 0x101a95668>