學習目標:
python學習十二,、
學習內(nèi)容:
1,、文件讀寫 2、StringIO和BytesIO 3,、操作文件和目錄 4,、序列化
1、文件讀寫
讀寫文件就是請求操作系統(tǒng)打開一個文件對象(通常稱為文件描述符),,然后,,通過操作系統(tǒng)提供的接口從這個文件對象中讀取數(shù)據(jù)(讀文件),或者把數(shù)據(jù)寫入這個文件對象(寫文件)
1,、讀文件
Python內(nèi)置的open()函數(shù),,傳入文件名和標示符,讀文件的模式打開一個文件對象 調(diào)用read()方法可以一次讀取文件的全部內(nèi)容,,Python把內(nèi)容讀到內(nèi)存,,用一個str對象表示 yyt.txt當我沒有加路徑時時默認當前路徑,在yyt.txt前也可與加上路徑 encoding可以選擇文件的編碼方式 在最后記得用close關(guān)閉文件,,否則會占用系統(tǒng)內(nèi)存,,操作系統(tǒng)能同時打開的文件是有限的
f = open('yyt.txt','r',encoding='utf-8')
print(f.read())
f.close()
輸出:
歡迎來到德萊聯(lián)盟!??!
由于讀取文件時可能會報錯,就不會調(diào)用后面的close函數(shù),,于是就可以用try…finally來實現(xiàn)最后都會實現(xiàn)close函數(shù) 調(diào)用read()會一次性讀取文件的全部內(nèi)容,,可以調(diào)用read(size)方法,每次最多讀取size個字節(jié)的內(nèi)容 調(diào)用readline()可以每次讀取一行內(nèi)容,,調(diào)用readlines()一次讀取所有內(nèi)容并按行返回list 如果有字符編碼的錯誤,,可以在encoding后面接一個errors='ignore’忽略掉
try:
f = open('yyt.txt','r',encoding='utf-8')
print(f.read())
finally:
if f:
f.close()
輸出:
歡迎來到德萊聯(lián)盟!??!
with open('yyt.txt', 'r') as f:
print(f.read())
輸出:
歡迎來到德萊聯(lián)盟!??!
讀取二進制文件,,比如圖片、視頻等等,,用’rb’模式打開文件
try:
f = open('1.jpg','rb')
print(f.read())
finally:
if f:
f.close()
輸出:
5(\xd9\xd5\xa4\xe1M87\x18\xc63U%\x05-f\x94\x1a_\x...
2,、寫文件 寫文件與讀文件差不多,只不過傳入標識符’w’覆蓋寫入或者’wb’表示寫文本文件或?qū)懚M制文件,,'w '覆蓋寫入并且可讀,,'a '追加寫入并且可讀(a寫入時光標默認在尾部,可以用.seek()函數(shù)把光標移動位置)
close函數(shù)在寫入函數(shù)時,,操作系統(tǒng)才保證把沒有寫入的數(shù)據(jù)全部寫入磁盤 如果沒有調(diào)用時,,close()的后果是數(shù)據(jù)可能只寫了一部分到磁盤,剩下的丟失了
f = open('test.txt', 'w')
f.write('Hello, world!')
f.close()
with open('test1.txt', 'a ') as f:
f.write('Hello, world!')
a = 'test.txt'
with open(a, 'a ') as f:
f.write('hello world !!!')
f.seek(0)
c = f.read()
print(c)
運行了四次f的輸出:
hello world !!!hello world !!!hello world !!!hello world !!!
從網(wǎng)上下載圖片到默認目錄
import requests
source = requests.get('http://pic.netbian.com/uploads/allimg/170725/103840-150095032034c0.jpg').content
print(source)
yyt = open('yt.jpg','wb')
yyt.write(source)
yyt.close()
從網(wǎng)上某個頁面提取某些信息
import requests
import json
source = json.loads(requests.get('http://www./api/report/ShowReport/data?SHOWTYPE=JSON&CATALOGID=1803&loading=first&random=0.5255326853258788').text)
for i in source[0]['data']:
print(i['zbmc'],i['brsz'],i['bsrzj'])
輸出:
深證成指 14,026.66 55.97
深證綜指 2,301.83 11.49
中小板指 9,273.68 67.74
創(chuàng)業(yè)板指 2,730.84 18.31
上市公司數(shù) 2,336 1
上市證券數(shù) 11,374 -3
股票總股本(億) 22,753.28 41.90
股票流通股本(億) 18,748.88 1.20
股票總市值(億元) 335,779.03 1965.38
股票流通市值(億元) 259,774.23 1183.62
股票成交金額(億元) 4,204.59 -554.64
平均股票價格(元) 14.75 0.05
股票平均市盈率 33.89 0.18
股票平均換手率 1.72 -0.30
2,、StringIO和BytesIO
數(shù)據(jù)讀寫不一定是文件,,也可以在內(nèi)存中讀寫 1、StringIO StringIO在內(nèi)存中讀寫str
先創(chuàng)建一個StringIO,,然后,像文件一樣寫入,,getvalue()方法用于獲得寫入后的str
from io import StringIO
f = StringIO()
f.write('hello')
print(f.getvalue())
輸出:
hello
讀取StringIO,,可以用一個str初始化StringIO,然后,,像讀文件一樣讀取
from io import StringIO
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
s = f.readline()
if s == '':
break
print(s.strip())
輸出:
Hello!
Hi!
Goodbye!
2,、BytesIO BytesIO實現(xiàn)了在內(nèi)存中讀寫bytes
創(chuàng)建一個BytesIO,然后寫入一些bytes,,二進制字符編碼一般是utf-8
from io import BytesIO
f = BytesIO()
f.write('hello world'.encode('utf-8'))
print(f.getvalue())
輸出:
b'hello world'
StringIO類似,,可以用一個bytes初始化BytesIO,然后,,像讀文件一樣讀取
from io import BytesIO
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f.read())
輸出:
b'\xe4\xb8\xad\xe6\x96\x87'
3,、操作文件和目錄
操作系統(tǒng)提供的命令簡單地調(diào)用了操作系統(tǒng)提供的接口函數(shù),Python內(nèi)置的os模塊也可以直接調(diào)用操作系統(tǒng)提供的接口函數(shù)
查看主機操作系統(tǒng)
import os
print(os.name)
輸出:
nt
查看,、創(chuàng)建和刪除,、重命名目錄
import os.path
print(os.path.abspath('.')) #查看當前目錄的絕對路徑
print(os.path.join('F:\pycharm\project','testdir')) #創(chuàng)建一個新目錄,首先把新目錄的完整路徑表示出來
print(os.mkdir('F:/pycharm/project/testdir')) #創(chuàng)建一個目錄
os.remove('F:/pycharm/project/testdir') #刪除目錄
print(os.rename('testdir','yyt')) #重命名
os.remove('yyt') #刪除目錄
創(chuàng)建一個29的文件夾,,并檢查是否有文件夾29
import os
if os.path.isdir('29'):
pass
else:
os.mkdir('29')
列出當前目錄下的所有目錄
import os
print([x for x in os.listdir('.') if os.path.isdir(x)])
找出目錄下的.py文件
import os
print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']) #os.path.splitext()可以直接讓你得到文件擴展名,,一般為兩部分第二部分為[1]
輸出:
['eleven.py', 'six.py', 'test.py', 'twelve.py']
os.path.join()函數(shù),把兩個路徑合成一個 os.path.split()函數(shù),,把一個路徑拆分為兩部分,,后一部分總是最后級別的目錄或文件名 os.path.splitext()可以直接讓你得到文件擴展名,一般為兩部分第二部分為[1]
4,、序列化
把變量從內(nèi)存中變成可存儲或傳輸?shù)倪^程稱之為序列化,,序列化在Python中叫pickling
序列化(pickling):就可以把序列化后的內(nèi)容寫入磁盤,,或者通過網(wǎng)絡傳輸?shù)絼e的機器上 反序列化(unpikling):把變量內(nèi)容從序列化的對象重新讀到內(nèi)存里
Python提供了pickle模塊來實現(xiàn)序列化
1、pickle.dumps/pickle.dump(向本地寫入文件)
pickle.dumps()方法把任意對象序列化成一個bytes,,把這個bytes寫入文件 pickle.dump()直接把對象序列化后寫入一個file-like Object
import pickle
d = dict(name='Bob',age=36,source=88)
print(pickle.dumps(d))
輸出:
b'\x80\x04\x95%\x00\x00\...
import pickle
d = dict(name='Bob',age=36,source=88)
f = open('dump.txt', 'wb') #會寫入一個dump.txt二進制文件
pickle.dump(d, f)
f.close()
2,、pickle.loads()/pickle.load()(讀取本地文件)
pickle.loads():把對象從磁盤讀到內(nèi)存時,可以先把內(nèi)容讀到一個bytes,,然后反序列化出對象 pickle.load():直接從一個file-like Object中直接反序列化出對象
import pickle
f = open('dump.txt','rb')
d=pickle.load(f)
f.close()
print(d)
輸出:
{'name': 'Bob', 'age': 36, 'source': 88}
3,、JSON JSON是一個序列化標準,JSON表示出來就是一個字符串,,可以被所有語言讀取,,也可以方便地存儲到磁盤或者通過網(wǎng)絡傳輸,比XML更快,,而且可以直接在Web頁面中讀取
JSON和Python內(nèi)置的數(shù)據(jù)類型對應如下:
python內(nèi)置的json模塊提供了非常完善的Python對象到JSON格式的轉(zhuǎn)換 JSON編碼是UTF-8,,所以我們總是能正確地在Python的str與JSON的字符串之間轉(zhuǎn)換
dumps()方法返回一個str,內(nèi)容就是標準的JSON,;dump()方法也可以直接把JSON寫入一個file-like Object(存入一個文件)
import json
d = dict(name='Bob', age=20, score=88)
print(json.dumps(d))
輸出:
{"name": "Bob", "age": 20, "score": 88}
JSON反序列化為Python對象,,用loads()或者對應的load()方法,前者把JSON的字符串反序列化,,后者從file-like-Object中讀取字符串并反序列化(讀出一個文件)
import json
d = '{"name": "Bob", "age": 20, "score": 88}'
print(json.loads(d))
輸出:
{'name': 'Bob', 'age': 20, 'score': 88}
import json
lists = [{'wang':'ning','水果':['大蒜','姜','蘿卜']},{'error':0}]
a = json.dumps(lists)
print(a)
b = json.loads(a)
print(b)
JSON進階:Python的dict對象可以直接序列化為JSON的{},,常用class表示對象,比如定義Student類,,然后序列化
首先寫一個類,,再寫一個函數(shù)把類轉(zhuǎn)換為dict,因為JSON無法把class序列化并且class自帶dict屬性
一般形式:
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
print(json.dumps(s, default=student2dict))
以為類一直可以變化所以把任意class的實例變?yōu)閐ict
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
print(json.dumps(s, default=lambda obj: obj.__dict__)) #把任意class的實例變?yōu)閐ict
輸出:
{"name": "Bob", "age": 20, "score": 88}
來源:https://www./content-1-777001.html