Python对csv、ini、xml、excel等格式文件操作用例
时间:2022-09-11 19:00:00
Python文件操作相关
- 文件操作
- 文件夹和路径
- csv格式文件
- ini格式文件
- xml格式文件
- excel文件
1. 文件操作
在学习文件操作之前,先回顾编码和数据类型的相关知识。
-
字符串类型(str),在程序中表示文本信息本质上是unicode编码中的二进制。
name = "刘小伟"
-
字节类型(bytes)
-
本质上可以表示文本信息utf-8/gbk二进制等编码(对unicode压缩,方便文件存储和网络传输。
name = "刘小伟" data = name.encode('utf-8') print(data) # b'\xe5\x88\x98\xe5\xb0\x8f\xe4\xbc\x9f' result = data.decode('utf-8') print(result) # "刘小伟"
-
可以表示原始二进制(图片、文件等信息)
-
1.1 读文件
-
读文本文件
# 1.打开文件 # - 路径: # 相对路径:info.txt' # 绝对路径:'//Users/liuxiaowei/PycharmProjects/路飞全栈//路飞全栈///路飞全栈//路飞全栈//路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞全栈/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路飞/路/路/路飞/路飞/路飞/路/路/路/路/路/路/路/路飞/路飞/路飞/路/路/路/路/路day09/files/info.txt' # - 模式 # rb,读取文件原始的二进制(r, 读 read;b, 二进制 binary;) # 1.打开文件 file_object = open('files/info.txt', mode='rb') # 2.读取文件内容并赋值data data = file_object.read() # 3.关闭文件 file_object.close() print(data) # b'alex-123\n\xe6\xad\xa6\xe6\xb2\x9b\xe9\xbd\x90-123' text = data.decode("utf-8") print(text)
# 1.打开文件 file_object = open('files/info.txt', mode='rt', encoding='utf-8') # 2.读取文件内容,并赋值给data data = file_object.read() # 3.关闭文件 file_object.close() print(data)
-
读图片等非文本内容文件。
file_object = open('files/美女.png', mode='rb') data = file_object.read() file_object.close() print(data) # \x91\xf6\xf2\x83\x8aQFfv\x8b7\xcc\xed\xc3}\x7fT\x9d{.3.\xf1{\xe8\...
注意事项:
-
路径
-
相对路径,你的程序到底在哪里运行的?
-
绝对路径
# 1.打开文件 file_object = open('/Users/liuxiaowei/PycharmProjects/路飞全栈/day09/files/info.txt', mode='rt', encoding='utf-8') # 2.读取文件内容,并赋值给data data = file_object.read() # 3.关闭文件 file_object.close()
windows系统中写绝对路径容易出问题:
# file_object = open('C:\\new\\info.txt', mode='rt', encoding='utf-8') file_object = open(r'C:\new\info.txt', mode='rt', encoding='utf-8') data = file_object.read() file_object.close() print(data)
-
-
读文件时,文件不存在程序会报错
Traceback (most recent call last): File "/Users/liuxiaowei/PycharmProjects/路飞全栈/day09/2.读文件.py", line 2, in <module> file_object = open('infower.txt', mode='rt', encoding='utf-8') FileNotFoundError: [Errno 2] No such file or directory: 'infower.txt'
# 判断路径是否存在? import os file_path = "/Users/liuxiaowei/PycharmProjects/路飞全栈/day09/files/info.txt" exists = os.path.exists(file_path) if exists: # 1.打开文件 file_object = open('files/info.txt', mode='rt', encoding='utf-8') # 2.读取文件内容,并赋值给data data = file_object.read() # 3.关闭文件 file_object.close() print(data) else: print("文件不存在")
1.2 写文件
-
写文本文件
# 1.打开文件 # 路径:t1.txt # 模式:wb(要求写入的内容需要是字节类型) file_object = open("files/t1.txt", mode='wb') # 2.写入内容 file_object.write( "刘小伟".encode("utf-8") ) # 3.文件关闭 file_object.close()
file_object = open("files/t1.txt", mode='wt', encoding='utf-8') file_object.write("刘小伟") file_object.close()
-
写图片等文件
f1 = open('files/a1.png',mode='rb') content = f1.read() f1.close() f2 = open('a2.png',mode='wb') f2.write(content) f2.close()
基础案例
# 案例1:用户注册
user = input("请输入用户名:")
pwd = input("请输入密码:")
data = f"{
usre}-{
pwd}"
file_object = open("files/info.txt", mode='wt', encoding='utf-8')
file_object.write(data)
file_object.close()
""" # 案例2:多用户注册 """
# w写入文件,先清空文件;再在文件中写入内容。
file_object = open("files/info.txt", mode='wt', encoding='utf-8')
while True:
user = input("请输入用户名:")
if user.upper() == "Q":
break
pwd = input("请输入密码:")
data = f"{
user}-{
pwd}\n"
file_object.write(data)
file_object.close()
注意事项:
- 路径
- 绝对路径
- 相对路径
- 文件不存在时,w模式会新建然后再写入内容;文件存在时,w模式会清空文件再写入内容。
1.3 文件打开模式
上文我们基于文件操作基本实现了读、写的功能,其中涉及的文件操作模式:rt、rb、wt、wb,其实在文件操作中还有其他的很多模式。
========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' create a new file and open it for writing
'a' open for writing, appending to the end of the file if it exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
The default mode is 'rt' (open for reading text).
关于文件的打开模式常见应用有:
-
只读:
r
、rt
、rb
(用)- 存在,读
- 不存在,报错
-
只写:
w
、wt
、wb
(用)- 存在,清空再写
- 不存在,创建再写
-
只写:
x
、xt
、xb
- 存在,报错
- 不存在,创建再写。
-
只写:
a
、at
、ab
【尾部追加】(用)- 存在,尾部追加。
- 不存在,创建再写。
-
读写
-
r+、rt+、rb+,默认光标位置:起始位置
file_object = open('files/info.txt', mode='rt+') # 读取内容 data = file_object.read() print(data) # 写入内容 file_object.write("你好呀") file_object.close()
file_object = open('files/info.txt', mode='rt+') # 写入内容 file_object.write("alex") # 读取内容 data = file_object.read() print(data) # -123 file_object.close()
-
w+、wt+、wb+,默认光标位置:起始位置(清空文件)
# 读取内容 data = file_object.read() print(data) # 写入内容 file_object.write("你好呀") # 将光标位置重置起始 file_object.seek(0) # 读取内容 data = file_object.read() print(data) file_object.close()
-
x+、xt+、xb+,默认光标位置:起始位置(新文件)
-
a+、at+、ab+,默认光标位置:末尾
file_object = open('files/info.txt', mode='at+') # 写入内容 file_object.write("武沛齐") # 将光标位置重置起始 file_object.seek(0) # 读取内容 data = file_object.read() print(data) file_object.close()
-
多用户注册案例
while True:
user = input("用户名:")
if user.upper() == "Q":
break
pwd = input("密码:")
data = "{}-{}\n".format(user, pwd)
file_object = open('files/account.txt', mode='a')
file_object.write(data)
file_object.close()
file_object = open('files/account.txt', mode='a')
while True:
user = input("用户名:")
if user.upper() == "Q":
break
pwd = input("密码:")
data = "{}-{}\n".format(user, pwd)
file_object.write(data)
file_object.close()
1.4 常见功能
在上述对文件的操作中,我们只使用了write和read来对文件进行读写,其实在文件操作中还有很多其他的功能来辅助实现更好的读写文件的内容。
-
read,读
-
读所有【常用】
f = open('info.txt', mode='r',encoding='utf-8') data = f.read() f.close()
f = open('info.txt', mode='rb') data = f.read() f.close()
-
读n个字符(字节)【会用到】
f = open('info.txt', mode='r', encoding='utf-8') # 读1个字符 data = f.read(1) f.close() print(data) # 刘
f = open('info.txt', mode='r',encoding='utf-8') # 读1个字符 chunk1 = f.read(1) chunk2 = f.read(2) print(chunk1,chunk2) f.close()
f = open('info.txt', mode='rb') # 读1个字节 data = f.read(3) f.close() print(data, type(data)) # b'\xe6\xad\xa6'
-
-
readline,读一行
f = open('info.txt', mode='r', encoding='utf-8') v1 = f.readline() print(v1) v2 = f.readline() print(v2) f.close()
f = open('info.txt', mode='r', encoding='utf-8') v1 = f.readline() print(v1) f.close() f = open('info.txt', mode='r', encoding='utf-8') v2 = f.readline() print(v2) f.close()
-
readlines,读所有行,每行作为列表的一个元素
f = open('info.txt', mode='rb') data_list = f.readlines() f.close() print(data_list)
-
循环,读大文件(readline加强版)【常见】
f = open('info.txt', mode='r', encoding='utf-8') for line in f: print(line.strip()) f.close()
-
write,写
f = open('info.txt', mode='a',encoding='utf-8') f.write("刘小伟") f.close()
f = open('info.txt', mode='ab') f.write( "刘小伟".encode("utf-8") ) f.close()
-
flush,刷到硬盘
f = open('info.txt', mode='a',encoding='utf-8') while True: # 不是写到了硬盘,而是写在缓冲区,系统会将缓冲区的内容刷到硬盘。 f.write("刘小伟") f.flush() f.close()
file_object = open('files/account.txt', mode='a') while True: user = input("用户名:") if user.upper() == "Q": break pwd = input("密码:") data = "{}-{}\n".format(user, pwd) file_object.write(data) file_object.flush() file_object.close()
-
移动光标位置(字节)
f = open('info.txt', mode='r+', encoding='utf-8') # r+ 读写 # 移动到指定字节的位置 f.seek(3) f.write("刘小伟") f.close()
注意:在a模式下,调用write在文件中写入内容时,永远只能将内容写入到尾部,不会写到光标的位置。
f = open('files/info.txt', mode = 'r+', encoding='utf-8') f.seek(2) f.write('李小龙') # 先将光标移动到最后,再写数据, 可能出现乱码, 因为"utf-8"编码3个字节一个汉字,seek(2),移动 # 第一个汉字的第2个字节 f.close()
-
获取当前光标位置
# 读字符 f = open('info.txt', mode='r', encoding='utf-8') p1 = f.tell() print(p1) # 0 f.read(3) # 读3个中文字符 3*3=9字节 , 如果是英文字符,那么p2是3,因为每个英文字符一个字节 p2 = f.tell() print(p2) # 9 f.close()
# 读字节 f = open('info.txt', mode='rb') p1 = f.tell() print(p1) # 0 f.read(3) # 读3个字节 p2 = f.tell() print(p2) # 3 f.close()
1.5 上下文管理
之前对文件进行操作时,每次都要打开和关闭文件,比较繁琐且容易忘记关闭文件。
以后再进行文件操作时,推荐大家使用with上下文管理,它可以自动实现关闭文件。
with open("xxxx.txt", mode='rb') as file_object:
data = file_object.read()
print(data)
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:
with open("xxxx.txt", mode='rb') as f1, open("xxxx.txt", mode='rb') as f2:
pass
练习题
-
补充代码:实现下载视频并保存到本地
import requests res = requests.get( url=" https://weibo.com/newlogin?tabtype=weibo&gid=1028032222&openLoginLayer=0&url=https%3A%2F%2Fweibo.com%2F&layerid=4791081306164660", headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" } ) # 视频的文件内容 data = res.content with open('files/video.mp4', mode='wb') as f: f.write(data)
-
日志分析,计算某用户
223.73.89.192
访问次数。日志文件如下:access.log
49.89.167.91 - - [17/Dec/2020:03:43:50 +0800] "GET /wiki/detail/3/40 HTTP/1.1" 301 0 "-" "Mozilla/5.0(Linux;Android 5.1.1;OPPO A33 Build/LMY47V;wv) AppleWebKit/537.36(KHTML,link Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 LieBaoFast/4.51.3" "-" 49.89.167.91 - - [17/Dec/2020:03:44:11 +0800] "GET /wiki/detail/3/40/ HTTP/1.1" 200 8033 "-" "Mozilla/5.0(Linux;Android 5.1.1;OPPO A33 Build/LMY47V;wv) AppleWebKit/537.36(KHTML,link Gecko) Version/4.0 Chrome/43.0.2357.121 Mobile Safari/537.36 LieBaoFast/4.51.3" "-" 203.208.60.66 - - [17/Dec/2020:03:47:58 +0800] "GET /media/uploads/2019/11/17/pic/s1.png HTTP/1.1" 200 710728 "-" "Googlebot-Image/1.0" "-" 223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /wiki/detail/3/40/ HTTP/1.1" 200 8033 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-" 223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/plugins/font-awesome/css/font-awesome.css HTTP/1.1" 200 37414 "https://pythonav.com/wiki/detail/3/40/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.60" "-" 223.73.89.192 - - [17/Dec/2020:03:48:26 +0800] "GET /static/stark/plugins/bootstrap/css/bootstrap.css HTTP/1.1" 200 146010 "https://pythonav.com/wiki/detail/3/40/"