创作不易,各位看官,点个赞收藏、关注必回关、QAQ、您的点赞是我更新的最大动力!
计算机中的所有的数据都是文件。
广义上说文件是按照文件的类型进行分类:如视频文件、音频文件、图片文件、文档文件等
等各种形式的文件,在这样的分类情况下~很明确使用对应的软件打开对应的文件。
狭义上的文件是按照组成文件的数据格式分类:
返回文章目录
打开: open(文件路径,操作权限[默认为r],编码方式)
关闭: 文件名.close()
读、文件名.read:
打开一个不存在的文件,会报错
"""
文件IO基本语法
UnicodeDecodeError: 'gbk'
Unicode解码错误,不能解码GBK编码
统一字符编码 国家标准编码
VSCode文件内容 :Unicode
命令行窗口:GBK编码
导致出现乱码,指定文件读取编码方式
"""
# 1. 打开文件:以读取文件内容的方式打开文件
file = open("d:/hello.txt", "r", encoding="UTF-8")
# file = open("d:/hello.txt",mode="r",encoding="UTF-8")
# 2. 读取文件内容
content = file.read()
# 3. 操作内容
print(content)
# 4. 关闭文件
file.close()
写 、文件名.write():
打开一个不存在的文件,会自动创建文件(不会创建目录),不会报错
"""
文件I/O 输入输出
向文件中写入数据:输出操作
"""
# 程序中的一段数据
info = "浔阳江头夜送客,枫叶荻花秋瑟瑟"
# 1、 打开文件
file = open("demo02_data.txt", "w", encoding="UTF-8")
# file = open("d:/hello.txt",mode="w",encoding="UTF-8")
# 2、 写入数据
file.write(info)
# 3、 关闭文件
file.close()
返回文章目录
文本文件 | ||
---|---|---|
读取操作 | r | 以只读方式打开文件。文件的指针将会放在文件的开头。 这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 | |
写操作 | w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 | |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 | |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 | |
二进制文件 | ||
---|---|---|
读取操作 | rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。一般用于非文本文件如图片等。注意:二进制文件把内容表示为一个特殊的bytes字符串类型。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 | |
写操作 | wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 | |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 | |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
返回文章目录
(一)读操作
1、read()
调用 read()会一次性读取文件的全部内容,如果文件有 10G,内存就爆了,会导致程序卡死, 所以,要保险起见,可以反复调用 read(size)方法,每次最多读取 size 个字符的内容,read(数目)
demo1.txt
www.baidu.com
www.baidu.com
www.baidu.com
file = open("demo1.txt","r")
a = file.read()
print(a)
file.close()
2、readline()
readline 每次读取一行,并且自带换行功能 每一行末尾会读到\n
同样可以指定长度,跟read一样
file = open("demo1.txt","r")
print(file.readline())
print(file.readline())
print(file.readline())
file.close()
``
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200512114531198.png)
**3、readlines()**
Readlines,一次性以行的形式读取文件的所有内容并返回一个 list,需要去遍历读出来
```python
file = open("demo1.txt","r")
print(file.readlines())
print(file.readlines())
print(file.readlines())
file.close()
file = open("demo1.txt","r")
ret = file.readlines()
for i in ret:
print(i,end="")
file.close()
4、循环读取 常用
file 句柄是一个可迭代的对象因此,可以循环读取文件中的内容,每次读一行
file = open("demo1.txt","r")
for i in file:
print(i,end="")
file.close()
(二)写操作
1、write()
w 指针在前,删除全部内容,重新写入
file = open("demo1.txt","w")
str = "写入操作"
file.write(str)
file.close()
2、writelines()
file.wrITelines(seq) #把 seq 的内容全部写到文件中(多行一次性写入)
file = open("demo1.txt","w")
lst = ["a","b","c"]
file.writelines(lst)
file.close()
Python 自带了 csv 模块提供用户对 csv 文件进行读写操作,要对 csv 文件进行写操作,首先 了解 csv 模块中的所有操作方法
这些操作方法中,最重要的就是关乎文件读写的 reader 模块和 writer 模块,这两个模 块分别设定了 CSV 文件的读写操作 下面分别就这两个模块的操作进行讲解
1、写入CSV文件
必须创建 csv 模块中对应的 writer 对象,通过 writer 对象完成文件内容的写入操作
import csv
# 系统数据
users = [
["稳稳", 18, "男", "稳稳@offcn.com"],
["老刘", 19, "男", "[email protected]"],
["小李", 16, "女", "[email protected]"]
]
file = open("stu_info.csv","w",newline="")#newline=“” 不需要\r换行
# 获取writer对象
writer = csv.writer(file)
# 写标题
writer.writerow(["姓名", "年龄", "性别", "邮箱"])
# 写入系统用户,保存用户数据
writer.writerows(users)
2、读取CSV文件
读取 csv 文件的操作,主要通过 csv 模块中的 reader 对象来完成,通过加载文件数据到 reader 对象中,文件中的数据就会按照固定的格式读取到程序中进行处理
import csv
file = open("stu_info.csv","r",newline="")
# 获取reader对象
reader = csv.reader(file)
for i in reader:
print(i)
file.close()
(四)with
使用 wIth 方式操作文件,可以不用关闭文件,会自动关闭文件
with open("demo1.txt","r",encoding="UTF-8") as file:
print(file.read())
with 内部实现了__enter__和 __exit__方法,会自动关闭文件
# with 内部实现了__enter__和 __exit__方法,会自动关闭文件
class Foo:
def __init__(self):
print("--init--")
def test(self):
print("--test--")
def __enter__(self):
print("--enter--")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("with执行完毕,调用exit")
with Foo() as f:
f.test()
print("最后一行代码")
(五)文件交互扩展
(1) shelve 存储数据到文件中[按照字典方式赋值即可]
"""
程序中的数据和二进制文件交互
shelve 可以打开文件后,直接读写文件
"""
import shelve
# (1) shelve 存储数据到文件中[按照字典方式赋值即可]
# 程序中有数据
i = 18
f = 3.14
lst = ["tom", "jerry"]
dct = {"username": "稳稳", "nickname": "C9"}
# 将程序中的数据存储到文件中
with shelve.open("mydata.txt") as file:
# 将文件当成字典:存储数据
file["age"] = i
file["pi"] = f
file["names"] = lst
file["damu"] = dct
'''
生成三个文件
bak文件:备份文件
dir文件:描述变量数据位置的文件
dat文件:数据文件,保存了真实数据
'''
# (2)按照字典的方式读取数据
# 默认会加载mydata.txt.dat、mydata.txt.dir
with shelve.open("mydata.txt") as file:
a1 = file["age"]
a2 = file["pi"]
a3 = file["names"]
a4 = file["damu"]
print(a1, type(a1))
print(a2, type(a2))
print(a3, type(a3))
print(a4, type(a4))
返回文章目录
使用os模块对文件进行操作
常用的:
1、重命名文件 os.rename(旧文件名,新文件名)
import os
os.rename("demo_1.txt","demo_2.tx")
2、删除文件 os.remove(文件名)
import os
os.remove("demo_1.txt")
3、创建文件 创建单层目录 即文件甲 os.mkdir(目录名)
import os
#创建单层目录
os.mkdir("目录名")
4、创建多层目录 级联创建文件夹 os.makedirs(父目录/子目录/孙目录,…)
import os
# 多级目录
os.makedirs("A/B/C")
5、删除单层目录 os.rmdir(目录名)
import os
os.rmdir("A")
6、删除多级目录 os.removedirs(“父目录/子目录/孙目录”)
import os
os.removedir("A/B/C")
7、获取当前所在目录 getwcd() 获取的是绝对路径
import os
path = os.getcwd()
print(path)
8、获取目录里面列表
import os
lst = os.listdir(os.getwcd())
print(lst)
9、切换所在目录 chdir()
import os
os.chdir("所需要切换的路径名")
#可以验证一下 发现目录已经切换到 所输入的路径
path = os.getcwd()
print(path)
10、判断文件或者文件夹是否存在
import os
# 找文件
print(os.path.exists("1.py"))
#存在就返回Tru
#path 可以换成需要查询的路径
# 找目录
print(os.path.exists("os"))
11、判断是否为文件 os.path.isfile() 输出得到bool
import os
print(os.path.isfile("1.py"))
12、判断是否是目录 os.path.isdir()输出得到bool
import os
print(os.path.isdir("test"))
13、获取绝对路径
import os
print(os.path.abspath("1.py"))
14、判断是否为绝对路径
import os
print(os.path.isabs("绝对路径")) # 返回bool
15、获取路径中的最后部分
import os
print(os.path.basename("1.py"))
16.获取路径中的路径部分
os.path.dirname("略")
17.文件定位
# tell() 查看文件定位
# with open("test.txt","a") as f:#指针 在后面 13 个字符
# with open("test.txt","r") as f: #指针 在前面 0 个字符
# print(f.tell())
#seek(offset,whence) offset偏移量 ,whence定位(0文件开头,1定位不变,2文件结尾)
with open("test.txt","r") as f:
print(f.tell())
f.seek(2,0)
print(f.tell())
print(f.read())
(六)文件复制
1、封装函数,可以实现文件复制(先读取目标文件,再写入新文件)
将111.txt复制一份 文件名为222.txt
def copy(file1,file2):
with open(file1,"r",encoding="UTF-8") as a:
content = a.read()
with open(file2,"w",encoding="UTF-8") as b :
b.write(content)
copy("111.txt","222.txt")
2、封装函数,可以实现文件备份(先读取目标文件,再写入新文件)
将111.txt复制一份,文件名为111.txt
def copy(file1):
with open(file1,"r",encoding="UTF-8") as a:
content = a.read()
with open("111_副本.txt","w",encoding="UTF-8") as b:
b.write(content)
copy("111.txt")
3、封装函数,打印某个文件内的所有的文件名
import os
def show_file(dir_path): #传递一个目录
file_lst = os.listdir(dir_path)
# print(file_lst)
for f in file_lst: #边路目录列表
path = dir_path+"/"+f
# print(path)
if os.path.isfile(path): # 判断是否是文件,直接打印
print(path)
elif os.path.isdir(path): # 如果是目录递归调用
show_file(path)
show_file(r"绝对路径名")
返回文章目录
可以通过需求来解决,如果作为一个软件开发者,开发的一个App,其中有用户注册
可能会出现以下问题:
age = int(input("请输入年龄:"))
(二)常见内建异常
① ValueError
值错误:操作的数据出现问题int(“a”): 类型转换,输入了数据~非数字字符,ValueError |
② NameError
名称错误:操作的变量出现问题 print(name):打印变量中的数据,变量 name 没有定义:NameError |
③ IndexError
索引错误:操作有索引的有顺序的数据时会出现的问题 names = [“tom”, “jerry”] print(names[2]) :获取列表中指定索引编号位置的数据:IndexError |
④ InterruptError
程序中断错误:通常是人为中断正在执行的程序 s = input(“请输入您的年龄:”) 请输入您的年龄:[Ctrl + C] :KeyboardInterrupt 键盘中断程序 |
⑤ KeyError
键错误:键值对数据中根据 key 操作时出现的问题 d = {“name”: “tom”} d[“age”] 字典中查询不到对应的 key,出现错误:KeyError |
返回文章目录
# 如果发生的异常类型和捕获的异常类型不相同,还是不能捕获异常,程序还会结束
try:
print(1/0)
except ZeroDivisionError: # 不写异常类型 默认捕获所有异常 Exception BaseException
print("异常,执行此处代码")
else:
print(" 程序正常执行 执行此处代码")
finally:
print(" 无论是否异常,都执行此处 比如文档关闭 ")
(二)处理异常
1、处理单个异常
程序代码中,只有一个异常信息,需要处理保证程序正常运行
try :
# 用户输入个人资料[年龄]
age = int(input("请输入您的年龄"))
print(f"用户的年龄为{age}")
except ValueError as e :
print("程序中出现了错误",e)
print("用户输入了非法年龄")
# (1) 精细处理多个异常
try:
# 从文件中读取数据
users_file = open("d:/test.txt", "r")
# 用户录入信息
s = int(input("请输入年龄"))
# ...
# 存储数据到文件中
users_file2 = open("d:/test.txt", "w")
except FileNotFoundError as e: # 处理第一个异常
print("文件没有找到,出现了异常", e)
except ValueError as e: # 处理第二个异常
print("用户输入了非法数据", e)
print("程序正常运行")
# # (2) 统一处理多个异常
# try:
# # 从文件中读取数据
# users_file = open("d:/test.txt", "r")
#
# # 用户录入信息
# s = int(input("请输入年龄"))
# # ...
# # 存储数据到文件中
# users_file2 = open("d:/test.txt", "w")
# except (FileNotFoundError, ValueError) as e: # 处理(可能出现的多个)异常
# print("出现了异常", e)
#
# print("程序正常运行")
返回文章目录
try :
name = input("请输入注册用户名")
if name.isalpha():
raise Exception("不可以全部是字母")
except Exception as e :
print(e)
比较传统异常,抛出了异常英文,作为管理者信息应该为自定义中文为好
(二)抛出自定义异常
用户注册:
输入注册用户名 如果长度小于5 抛出异常,输出异常:输入用户名过短
"""
用户注册:
输入注册用户名 如果长度小于5 抛出异常,输出异常:输入用户名过短
"""
class ShortInputException(Exception):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return self.msg
try:
name = input("请输入注册用户名:")
if len(name)<5:
raise ShortInputException("输入用户过短")
except Exception as e:
print(e)
Python内部已经实现了自定义异常,继承父类的时候Exception,所有里面内容可以直接为pass
"""
用户注册:
输入注册用户名 如果长度小于5 抛出异常,输出异常:输入用户名过短
"""
class ShortInputException(Exception):
# def __init__(self,msg):
# self.msg = msg
#
#
# def __str__(self):
# return self.msg
pass
try:
name = input("请输入注册用户名:")
if len(name)<5:
raise ShortInputException("输入用户过短")
except Exception as e:
print(e)
自定义异常需求案例:
判断输入的字符串长度,如果小于指定长度,就抛出自定义异常
class ShortInputException(Exception):
def __init__(self,length,atleast):
self.length = length
self.atleast = atleast
def __str__(self):
return f"您输入的字符串长度为{self.length},规定长度为{self.atleast}"
try:
content = input("请输入一个字符串:")
if len(content)<5:
raise ShortInputException(len(content),5)
except Exception as e:
print(e)
返回文章目录