本文所讲内容如下:
- 文件打开与关闭
- 文件读写
- csv文件
- 文件与文件夹操作
- 对象序列化
文件分为二进制文件与文本文件(TXT)
其中二进制文件无法直接理解,文本文件可以理解。
文件的打开和关闭
with open语句
with open (file_name [,mode='r',encoding=None]) as fp:
文件操作语句
•
file_name:文件名指定了被打开的文件名称。
•
mode:
打开模式指定了打开文件后的处理方式,默认读操作。
•
参数
encoding
指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式,如
GBK
、
utf8
、
CP936
等等。
tip:
使用with open语句可以实现在with open 语句结束后,自动关闭文件流。(这是与open函数需要自己写close函数关闭文件流的重要区别。)
open语句
open
语句适用于对资源进行访问的场合,使用
open
打开文件,必须要使用
close
关闭文件
open(file_name [,mode='r',encoding=None]) as fp:文件操作语句
直接打开文件,如果出现异常(如,读取文件过程中文件不存在),则直接出现错误,close命令无法执行,文件无法关闭。
•
用
with
语句的好处就是到达语句末尾时会自动关闭文件,即使出现异常。
•
默认为只读文本文件,编码默认为
Unicode
。
文件路径
绝对路径(从根目录开始)
with open(r'C:\Users\Administrator\Desktop\Files\data\test.txt')
就是从菜单栏直接复制所得到的路径
实例
with open(r'F:\1.txt','w') as f:
f.write('i am a good boy!\n')
f.write('i want to enter Tsing hua University!\n')
f.write('胜利一定属于我!')
相对路径(相对于程序的当前工作目录)
with open(r'./data/test.txt') as f:
with open(r'test.txt') as f :
./表示当前文件所在目录
../表示当前文件所在目录的上一级目录
实例
xxx.py打开打开aa.txt,在文件目录之下,两者是同级目录
with open (r'./a_file/aa.txt','r') as f:
a_file
中的
ab.py
尝试打开
b_file
下的
a.txt
:首先定位到上级目录,在上级目录下找到b_file下的
a.txt
with open (r'../b_file/a.txt','r') as f:
文本文件的编码
ASCII
码,即美国标准信息交换码,采用
8
位
1
字节)编码,因此最多只能表示
256
个字符。(
10+26+26+
其他)
UTF-8
编码是国际通用的编码,用
8
位(
1
字节)表示英语(兼容
ASCII
码),以
24
位(
3
字节)表示中文及其他语言。
GBK2312
编码是中国制定的中文编码,用
1
字节表示英文字符,用
2
字节表示汉
字字符。
Unicode
是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。采
用 不同的编码方式,写入文件的内容可能是不同的。就汉字编码而言,
GBK
编
码的
1
个汉字占
2
个字符,
UTF-8
编码的
1
个汉字占
3
个字符,
Unicode
编码中的
1
个汉字占
1
个字符。
tip:
如果使用
with open
和
open
函数打开文件时,如果没有注明访问模式,则必须保
证文件是存在的,否则就会报异常。
默认读文件操作。
文件模式
在文件中写入数据需要指明文件的访问模式。
有关二进制文件:
图片、音频、视频这些文件本质上都是由二进制码组成的,由于有特定的保存格
式和对应的解析方式,才可以看到这些形形色色的多媒体。所以,想要抓取它们,
就要拿到它们的二进制码 。
顺序写入
•
write
:写入数据追加到文件末尾
•
writelines:
向文件中写入一序列的字符串
顺序读取
•
read
:顺序读取固定长度的数据
•
readlines
:顺序逐行一次性读取全部数据
•
readline
:顺序读取一行数据
定位读写
•
tell
:定位读写位置
•
seek
:指定位置读写
write函数
若不存在,新建文件
;
若存在,清空并重输入
fileobjext.write([str])
with open(r'F:\1.txt','w') as f:
f.write('i am a good boy!\n')
f.write('i want to enter Tsing hua University!\n')
f.write('胜利一定属于我!')
writelines——写入预定义字符串
fileobjext.writelines([str])
>>> with open('./data/test.txt','w') as file:
>>> seq = ["菜鸟教程 1\n", "菜鸟教程 2"]
>>> file.writelines( seq )
read函数
read()
方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
fileobjext.read([size])
>>> with open('./data/test.txt','r') as file:
>>> content=file.read(4)
>>> print(content)
readlines——顺序全部读取
readlines()
方法用于一次性读取文件所有内容并返回一个列表,其中列表中每
个元素对应原文件每一行数据。
fileobjext.readlines()
with open('./data/test.txt','r') as file:
>>> content=file.readlines()
>>> print(content)
#['1,hellow word! \n', '2,hellow word! \n', '3,hellow word! \n']
readline——顺序按行读取
fileobjext.readline()
>>> with open('./data/test.txt','r') as file:
>>> content=file.readline()
>>> print(content)
# 1,hellow word! \n
tell——获取当前读写位置
tell() 方法返回文件的当前位置,即文件指针当前位置。
fileobjext.tell() #无参数
>>> with open('./data/test.txt','r') as file:
>>> line = file.readline()
>>> print ("读取的数据为: %s" % (line))
>>> position = file.tell()
>>> print ("当前位置: %d" % (position))
seek——查找该位置
指定位置开始读取或者写入文件的数据
seek(offset, from)
•
offset:表示偏移量,也就是代表需要移动偏移的字节数
•
from:
表示方向,可以指定从哪个位置开始偏移
•
0:
表示文件开头(默认值)
•
1:
表示当前位置
•
2:
表示文件末尾
seek实际上可以理解为调整指针指向的函数,具体例子如下
with open(r'F:\1.txt','r') as f:
info=f.readlines()
print(info)
# f.write('i am a good boy!\n')
# f.writ(e('i want to enter Tsing hua University!\n')
# # f.write'胜利一定属于我!')
print(f.tell())
print(f.seek(800))
print(f.tell())
由上图可见,指针的位置在seek函数后变成了800
close语句
写入文件完成后,应使用
close()
方法关闭文件,以释放资源。
f.close() #关闭文件
也可以使用
finally
字句,以保证即使发生异常,也会关闭打开的文件。
>>> f = open(‘data.txt’, ‘w’)
>>> try:
>>> finally:
>>> f.close()
通常文件操作一般采用
with open
语句,以保证自动关闭打开的文件
>>> with open('data.txt','w') as f:
>>> f.write('123\n')
csv文件
逗号分隔值
(Comma-Separated Values
,
CSV
,有时也称为字符分隔值,因为分
隔字符也可以不是逗号
)
,其文件以纯文本形式存储表格数据(数字和文本)
CSV
文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组
成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。
本质上是文本文件
,
文本编辑器打开可读性不高
Python
自带操作
CSV
的模块。使用这个模块,可以将
CSV
文件 的内容转换为
Python
的字典,从而方便使用。
要读取
CSV
文件,首先需要导入
Python
的
CSV
模块:
import csv
由于
CSV
文件本质上是一个文本文件,所以需要先以文本文件的方式打开,再将
文件对象传递给
csv
模块
with open(“a.csv”,”r”,encoding=“utf-8”) as csvfile: csv.reader(csvfile,dialect=“excel”, delimiter=“,”)
csvfile:
文件对象或列表对象
delimiter:
指定分隔符,默认是逗号
>>> with open('result.csv', encoding='utf-8') as f:
>>> reader = csv.reader(f)
>>> for row in reader:
>>> print(row)
返回对象
csv.reader
是可迭代的对象
返回对象的方法:
csvwrite.writerow(row):
写入一行数据
row
csvwrite.writerows(rows):
写入多行数据
rows
可迭代对象的每个元素作为一行,且行内元素间以逗号
(,)
相隔。
>>> import csv
>>> datas=["abcd","defg","hijk"]
>>> with open('example.csv', 'w', newline='') as f:
>>> writer = csv.writer(f)
>>> writer.writerows([datas])
# 不等价
>>> writer.writerows(datas)
DictReader(字典式)
>>> import csv
>>> with open('iris.csv') as f:
>>> reader=csv.DictReader(f)
>>> for row in reader:
>>> print('id为{}'.format(row['id']))
使用DictWriter类,可以写入字典形式的数据,同样键也是标头(表格第一行)
>>> import csv
>>> headers = [‘name’, ‘age’] #指定行头
>>> datas = [{'name':'Bob', 'age':23},
>>> {'name':'Jerry', 'age':44},
>>> {'name':'Tom', 'age':15}]
>>> with open('example.csv', 'w', newline='') as f:
>>> writer = csv.DictWriter(f, headers)
>>> writer.writeheader()
>>> for row in datas:
>>> writer.writerow(row)
>>> #writer.writerows(datas)
文件与文件基本操作
查看文件属性、复制和删除文件、创建和删除目录等属于文件和目录操作范畴。
常用的文件操作函数
•
os
模块和
os.path
模块提供了大量的操作文件名、文件属性、文件路径的方法
>>> import os
>>> os.getcwd() #返回当前工作目录
'C:\\Python35'
>>> os.mkdir(os.getcwd()+'\\temp') #创建目录
>>> os.chdir(os.getcwd()+'\\temp') #改变当前工作目录
>>> os.getcwd()
'C:\\Python35\\temp'
>>> os.mkdir(os.getcwd()+'\\test')
>>> os.listdir('.')
['test']
>>> os.rmdir('test') #删除目录
>>> os.listdir('.')
[]
os
模块中的
rename()方法可以完成文件的重命名。
rename(需要修改的文件名, 新的文件名)
os
模块中的
remove()方法可以完成文件的删除操作。
remove(待删除的文件名)
try-except_finally
对象序列化与反序列化
对象序列化:将对象转换为数据形式,并转储到磁盘文件或通过网络实现跨平台
传输。
对象反系列化:从磁盘数据文件或接收到的数据形式,恢复以得到相应对象的过
程。
优点
•
以某种存储形式使自定义对象持久化;
•
多个对象可以序列化存储到一个磁盘文件,用户不必关系数据的格式。
•
程序更具维护性,被广泛用于各种分布式并行处理系统中。
pickle模块和对象序列化
序列化
pickle.dump(obj,file,protocol=None) #将对象obj保存至文件file
反序列化
pickle.load(file) #从file中读取并重构一个对象
只用于python,且多版本见不兼容
序列化
>>> import pickle
>>> with open(r'dataObj1.dat', 'wb') as f:
>>> d1=dict(name='Mary', age=19)
>>> pickle.dump(d1, f)
反序列化
>>> import pickle
>>> with open(r'dataObj1.dat', 'rb') as f:
>>> o1=pickle.load(f)
>>> print(type(o1), str(o1))
JSON
在不同的编程语言之间传递对象时,需要将对象序列化为标准格式,例
XML
,但更
好的方法是序列化为
JSON(JavaScript Object Notation, JavaScript
对象标记
)
,
JSON
表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘
或者通过网络传输。
JSON
不仅是标准格式,可被所有主流语言生产和消费,并且比
XML
更快,而且可
以直接在
Web
页面中读取,非常方便。
跨语言进行信息传输
无序对象结构
{"firstName":"Brett",
"lastName":"McLaughlin",
"email":"aaaa"}
有序数组结构
{ "people":[
{"firstName":"Brett","email":"aaaa"},
{"firstName":"Jason","email":"bbbb"},
{"firstName":"Elliotte","email":"cccc"}]
}
Python
标准库模块
json
包含将
Python
对象编码为
JSON
格式(或者简称
JSON
)和将
JSON
解码到
Python
对象的函数。
•
json.dumps
(
obj
):把
obj
对象序列化为
JSON
字符串;
•
json.dump
(
obj,fp)
:把
obj
对象序列化为
JSON
字符串写人文件
fp
;
•
json.loads
(s):返回把
JSON
字符串
s
反序列化后的对象;
•
json.load(fp)
:返回把从文件
fp
中读取的
JSON
字符串反序列化后的对象
实例
>>> import json
>>> # 序列化
>>> with open('json_file','w') as f:
>>> dic = {'k1':'v1','k2':'v2','k3':'v3'}
>>> json.dump(dic,f) #dump方法直接将字典转换成json字符串写入文件
>>> # 反序列化
>>> with open(‘json_file’) as f:
>>> dic2 = json.load(f) #load方法直接将文件中的json字符串转换成字典
>>> print(type(dic2),dic2)
<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
爬虫案例
>>> import requests,json
>>> url="https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start=0"
>>> head={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/94.0.4606.71 Safari/537.36"}
>>> response= requests.get(url,headers=head)
>>> strs= response.text
>>> strs_json=json.loads(strs)
>>> print(f"爬虫对象的字符串形式解析前的格式为{type(strs)}")
>>> print(f"爬虫对象的字符串形式解析后的格式为{type(strs_json)}")
'''{"data":[{"directors":[" 陈凯歌 "," 徐 克 "," 林超贤
"],"rate":"7.6","cover_x":1080,"star":"40","title":" 长 津 湖
","url":"https:\\/\\/movie.douban.com\\/subject\\/25845392\\/","casts":["吴京","易烊千玺","段奕宏"," 朱亚文 "," 李 晨
"],"cover":"https://img9.doubanio.com\\/view\\/photo\\/s_ratio_poster\\/public\\/p2681329386.jpg","id":"25845392","cover_y":1513} '''
>>> import requests,json
>>> url="https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=&start=0"
>>> head={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/94.0.4606.71 Safari/537.36"}
>>> response= requests.get(url,headers=head)
>>> strs= response.text
>>> strs_json=json.loads(strs)
>>> print(f"爬虫对象的字符串形式解析前的格式为{type(strs)}")
>>> print(f"爬虫对象的字符串形式解析后的格式为{type(strs_json)}")
{'data': [{'directors': ['陈凯歌', '徐克', '林超贤'],
'rate': '7.6',
'cover_x': 1080,
'star': '40',
'title': '长津湖',
'url': 'https://movie.douban.com/subject/25845392/',
'casts': ['吴京', '易烊千玺', '段奕宏', '朱亚文', '李晨'],
'cover': 'https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2681329386.jpg',
'id': '25845392',
'cover_y': 1513} >>> strs_json['data'][1]['rate']