python3:文件与异常

[复制链接]
发表于 2025-9-5 06:27:29 | 显示全部楼层 |阅读模式
本来这篇教程是计划在base python数据类型之后出的,但是计划赶不上厘革,反正末了都要融会贯通,今日有时间、今天遇到了类似的题目,就今天做这一模块的整理,顺序不是重点。
参考我的上一篇博客:https://blog.csdn.net/weixin_62528784/article/details/144705158
本篇博客的核心在于File对象以及相应的open方法,OS对象以及相应的方法
参考:https://www.runoob.com/python/python-files-io.html

一,文件及文件基本操作
文件本质上也是数据,数据的聚集,文件操作和我们处置惩罚一些基本的python中数据类型本质上也没什么区别,
处置惩罚原子类型的数据,和处置惩罚聚集类型的数据

目录与文件,以linux的系统文件组织为主,这一块可以再重温一下:

1,谈到文件夹和文件,少不了的就是绝对路径以及相对路径了,

  1. # 绝对路径
  2. # 1,win系统中:
  3. win_path="C:\\Users\\Administrator\\Desktop\\generate.pl"
  4. # 2,linux系统中(主):
  5. linux_path="/data1/project/generate.pl"
复制代码
很简单,linux系统中pwd之类怎么写的文件路径,文件操作的时间只必要在外面再加上“”即可;
windows系统中同理,由于windows系统中路径的话,实在我们潜移默化已经习惯了盘符层层递进的写法,而且我们更早习惯了转义字符的概念,所以我们同样写路径+外面套双引号(注意路径中的盘符,以及转义符号即可,与linux习惯的反过来双层斜杠,我想用R读写文件习惯了的人,这一点底子应该很快就能够融汇贯通)。
2,别的必要提一下在python中对文件系统的一些常见的操作,在os模块下
(1)获取当前工作目录
  1. import os
  2. # 获取当前工作目录
  3. current_dir = os.getcwd()
  4. print(f"当前工作目录: {current_dir}")
复制代码

(2)修改当前工作目录
  1. # 修改当前工作目录
  2. os.chdir('/path/to/new/directory')
  3. print(f"修改后的工作目录: {os.getcwd()}")
复制代码

(3)创建目录
  1. # 创建单级目录
  2. os.mkdir('new_folder')
  3. # 创建多级目录
  4. os.makedirs('parent_folder/child_folder')
复制代码

(4)删除目录
  1. # 删除单级目录(目录必须为空)
  2. os.rmdir('new_folder')
  3. # 删除多级目录
  4. os.removedirs('parent_folder/child_folder')
复制代码

(5)检查路径是否存在
  1. # 检查路径是否存在
  2. path = '/path/to/check'
  3. if os.path.exists(path):
  4.     print(f"路径存在: {path}")
  5. else:
  6.     print(f"路径不存在: {path}")
复制代码

(6)判断路径类型
  1. path = '/path/to/check'
  2. # 判断是否为文件
  3. if os.path.isfile(path):
  4.     print(f"{path} 是一个文件")
  5. # 判断是否为目录
  6. if os.path.isdir(path):
  7.     print(f"{path} 是一个目录")
复制代码

(7)获取文件或目录的绝对路径
  1. # 获取绝对路径
  2. absolute_path = os.path.abspath('relative_path')
  3. print(f"绝对路径: {absolute_path}")
复制代码

(8)分割路径:
  1. path = '/path/to/file.txt'
  2. # 分割路径和文件名
  3. dir_name, file_name = os.path.split(path)
  4. print(f"目录: {dir_name}, 文件名: {file_name}")
  5. # 分割文件名和扩展名
  6. file_base, file_ext = os.path.splitext(file_name)
  7. print(f"文件名: {file_base}, 扩展名: {file_ext}")
复制代码
我实际应用的1个例子:
  1. file_path = "/data1/project/generate.pl"
  2. if os.path.exists(file_path):
  3.     print(f"路径{file_path}存在")
  4.     if os.path.isfile(file_path):
  5.         print(f"路径{file_path}是一个文件")
  6.         dir_name,file_name = os.path.split(file_path)
  7.         print(f"开始分割路径{file_path}为目录和文件\n")
  8.         print(f"目录为{dir_name},文件为{file_name}\n")
  9.         print(f"开始分割文件{file_path}为文件名和拓展名\n")
  10.         file_base,file_ext = os.path.splitext(file_name)
  11.         print(f"文件名为{file_base},拓展名为{file_ext}\n")
  12.         # 拓展名为.pl,我们可以通过[1:]来获取拓展名
  13.         print(f"实拓展名为{file_ext[1:]}\n")
  14.     else:
  15.         print(f"路径{file_path}是一个目录")
  16. else:
  17.     print(f"路径{file_path}不存在")
复制代码

(9)列出目录内容
  1. # 列出当前目录下的所有文件和子目录
  2. contents = os.listdir('.')
  3. print(f"目录内容: {contents}")
复制代码

(10)重定名文件或目录
  1. # 重命名文件或目录
  2. os.rename('old_name', 'new_name')
复制代码

(11)删除文件
  1. # 删除文件
  2. os.remove('file_to_delete.txt')
复制代码

(12)获取文件或目录的属性
  1. path = '/path/to/file_or_directory'
  2. # 获取文件大小(字节)
  3. size = os.path.getsize(path)
  4. print(f"文件大小: {size} 字节")
  5. # 获取最后修改时间
  6. mod_time = os.path.getmtime(path)
  7. print(f"最后修改时间: {mod_time}")
复制代码

(13)拼接路径
  1. # 拼接路径
  2. new_path = os.path.join('/path/to', 'subdir', 'file.txt')
  3. print(f"拼接后的路径: {new_path}")
  4. # 可以使用f"{os.getcwd()}"拼接当前工作路径
复制代码

(14)获取环境变量
  1. # 获取环境变量
  2. home_dir = os.environ.get('HOME')
  3. print(f"HOME 环境变量: {home_dir}")
复制代码

可以实验获取各种已经安装软件的环境变量,这一块操作比较私密,仅提供代码,不提供示例图。
获取全部环境变量:
  1. import os
  2. # 获取所有环境变量
  3. env_vars = os.environ
  4. # 打印所有环境变量
  5. for key, value in env_vars.items():
  6.     print(f"{key}: {value}")
复制代码
获取特定软件的环境变量:
假如你知道某个软件的环境变量前缀(比方 JAVA_HOME、PYTHONPATH 等),可以通过过滤来获取:
  1. # 获取与特定软件相关的环境变量(例如包含 "JAVA" 的变量)
  2. for key, value in os.environ.items():
  3.     if "JAVA" in key:
  4.         print(f"{key}: {value}")
复制代码
使用 os.environ.get 获取单个环境变量:
假如你知道具体的环境变量名称,可以直接获取:
  1. # 获取特定环境变量
  2. java_home = os.environ.get('JAVA_HOME')
  3. print(f"JAVA_HOME: {java_home}")
复制代码
将环境变量导出到当前会话:
假如必要在当前会话中设置新的环境变量,可以使用 os.environ:
  1. # 设置新的环境变量
  2. os.environ['MY_VAR'] = 'my_value'
  3. # 验证是否设置成功
  4. print(os.environ.get('MY_VAR'))  # 输出: my_value
复制代码
使用 subprocess 检察环境变量:
假如必要从子进程中获取环境变量,可以使用 subprocess 模块:
  1. import subprocess
  2. # 使用 `env` 命令列出所有环境变量(Linux/Mac)
  3. result = subprocess.run(['env'], capture_output=True, text=True)
  4. print(result.stdout)
  5. # 在 Windows 上可以使用 `set` 命令
  6. # result = subprocess.run(['set'], capture_output=True, text=True)
  7. # print(result.stdout)
复制代码
保存环境变量到文件:
假如必要将全部环境变量保存到文件中,可以这样操作:
  1. with open('env_vars.txt', 'w') as f:
  2.     for key, value in os.environ.items():
  3.         f.write(f"{key}: {value}\n")
复制代码
(15)实行系统下令
  1. # 执行系统命令
  2. os.system('ls -l')  # 在 Linux/Mac 上列出文件
  3. os.system('dir')    # 在 Windows 上列出文件
复制代码

用magic大概是os模块
3,文件操作

其中最常用的模式字符串:主要是r以及w

参考:https://www.runoob.com/python/python-files-io.html


模式描述t文本模式 (默认)。x写模式,新建一个文件,假如该文件已存在则会报错。b二进制模式。+打开一个文件举行更新(可读可写)。U通用换行模式(不保举)。r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。r+打开一个文件用于读写。文件指针将会放在文件的开头。rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。w打开一个文件只用于写入。假如该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。假如该文件不存在,创建新文件。wb以二进制格式打开一个文件只用于写入。假如该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。假如该文件不存在,创建新文件。一般用于非文本文件如图片等。w+打开一个文件用于读写。假如该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。假如该文件不存在,创建新文件。wb+以二进制格式打开一个文件用于读写。假如该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。假如该文件不存在,创建新文件。一般用于非文本文件如图片等。a打开一个文件用于追加。假如该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。假如该文件不存在,创建新文件举行写入。ab以二进制格式打开一个文件用于追加。假如该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。假如该文件不存在,创建新文件举行写入。a+打开一个文件用于读写。假如该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。假如该文件不存在,创建新文件用于读写。ab+以二进制格式打开一个文件用于追加。假如该文件已存在,文件指针将会放在文件的结尾。假如该文件不存在,创建新文件用于读写。(1)写文件:

注意,只有close才气将文件内容写入,并出现出来。
总之,open和close对应,只有在open后没有close前,才气正常写入文件;只有close之后,才气正常出现正常写入的文件内容。

重点就是比较其中的write以及writelines:

主要区别

特性**write****writelines**输入类型单个字符串字符串的可迭代对象(如列表、元组)写入方式一次写入一个字符串一次写入多个字符串换行处置惩罚必要手动添加换行符必要手动在每个字符串中添加换行符write顾名思义只能担当单个对象,writelines可以担当多个对象(字符串的可迭代对象)。
来个简单的例子:

上面的逻辑就是先写入字符内容,写完之后再判断字数有没有达到10个,10个一行,假如达到了就换行;
当然,我们也可以直接先判断是否达到10个一行的条件,假如达到了就输出字符以及换行符,否则正常打印:
  1. import os
  2. file1 = open("1000.txt","w")
  3. for i in range(1,101):
  4.     if i%10==0:
  5.         file1.write(f"{i}\n")
  6.     else:
  7.         file1.write(f"{i}\t")
  8. file1.close()
  9. os.system("cat 1000.txt")
复制代码

(2)读文件:

注意,要正常读取的话,照旧要思量close,大概文件对象的重新读取:

比如说对于文件对象file,我读取了前5个字符,假如没有close的话,我再接着读取出全部的内容,相称于是对剩下的file迭代内容举行读取。
在 Python 中,文件对象的 read() 方法是基于文件指针(file pointer)工作的。文件指针会随着每次读取操作而移动,因此第二次调用 read() 时,只能读取从上次读取结束位置到文件末尾的内容,而不是从文件开头重新读取。
文件指针的工作原理:
文件指针初始位置:当文件被打开时,文件指针默认位于文件的开头。
read(n) 的活动:
read(n) 会从当前文件指针的位置读取 n 个字符,并将文件指针移动到读取结束的位置。
read() 的活动:
假如不指定参数,read() 会从当前文件指针的位置读取到文件末尾。


一般麻烦的话,就直接多次打开文件对象举行读取:

总得来说:

大概将可迭代在读的过程中迭代,大概将读完的内容举行迭代

总之,文件IO操作基本操作如下:
  1. # 写操作
  2. # 最好就是使用writelines写入多个可迭代字符串对象
  3. file = open("path_to_file_to_write","w")
  4. file.writelines(["str1","str2","strn"]) # 所有的字符串内容
  5. # 读操作
  6. # 最好是for循环读取,对每一个line对象分别操作
  7. file = open("path_to_file_to_read","r")
  8. for line in file:
  9.     print(line,end="")
  10. # 或者是用readlines读出来,再
  11. file_content = file.readlines()
  12. # 因为file_content也是一个可迭代对象,可以对对其进行操作
复制代码
参考:https://liaoxuefeng.com/books/python/io/file/index.html

with语句能够主动帮我们调用close方法,所以为了养成良好的习惯,我们都使用with:
实在都是赋值的逻辑,本来的赋值逻辑"="变成了现在的“with as”语句形式
  1. file=open() ————> with open() as file
复制代码
  1. # 写操作
  2. # 最好就是使用writelines写入多个可迭代字符串对象
  3. with open("path_to_file_to_write","w") as file:
  4.     file.writelines(["str1","str2","strn"]) # 所有的字符串内容
  5. # 读操作
  6. # 最好是for循环读取,对每一个line对象分别操作
  7. with open("path_to_file_to_read","r") as file:
  8.     for line in file:
  9.         print(line,end="")
  10. # 或者是用readlines读出来,再
  11.     file_content = file.readlines()
  12. # 因为file_content也是一个可迭代对象,可以对对其进行操作
复制代码
二,csv文件处置惩罚
此处以csv文件代称任何简单字符分割的文件,比如说常见的csv、tsv(bed、txt、excel格式等本质都是前面)。

主要是base python中常用的就是csv模块,所以我们用csv文件操作指代任何更一般的分割符操作:

(1)csv写文件:

起首待写入的文件得有,得有一个待写入文件对象;
然后对于这个对象,我们要使用csv模块举行操作,将基本操作中的待写入文件对象转化为csv模块中的writer对象。
总之,由于我们要使用csv模块,所以我们得将基本文件对象转换为csv中的writer对象,大概是下面的read对象;
然后再使用writer对象的函数,比如说writerow,大概是下面reader对象的函数。
再然后和基本文件读写操作一样关上。
(打开文件,转化对象,开始写大概读,再关上——》打转写关)
  1. # csv文件写操作
  2. # 打转写关
  3. import csv
  4. file = open("test.csv","w") #打
  5. csv_writer = csv.writer(file) #转
  6. csv_writer.writerows([["姓名","年龄","性别"],["小明",18,"男"],["小红",19,"女"]]) #写
  7. # 注意写入的是1个可迭代对象,所以可以是1个列表,而每一个被迭代的元素是csv中的一行,所以也可以是一个列表
  8. file.close() #关
复制代码

同样的,我们写单个字符用writerow,假如是写入一个可迭代对象就writerows
(2)csv读文件

然后注意对于reader对象,实际上是没有read、readline、readlines等函数方法的,

所以实际上照旧得使用for循环,取出每一个可迭代对象,

可以看出来读出来的每一个对象都是列表list
  1. # 基本逻辑都是:
  2. # 1,打开文件,如果是读csv文件,就open+r;如果是写csv文件,就open+w,按照前面文件基本读写模式
  3. # 2,对打开的文件可操作对象进行转换(这样才方便使用对应csv对象中的实现方法)
  4. # 3,writer写对象就用写方法,reader读对象就用读方法
  5. # 4,读写完毕之后对于最初打开的文件可操作对象要关闭
  6. # 写:打转写关
  7. import csv
  8. file = open("path_to_csv_to_write.csv","w") #打
  9. csv_writer = csv.writer(file) #转
  10. csv_writer.writerows([1个可迭代对象]) #写
  11. file.close() #关
  12. # 读:打转读关
  13. import csv
  14. file = open("path_to_csv_to_read.csv","r") #打
  15. csv_reader = csv.reader(file) #转
  16. for row in csv_reader:
  17.     print(row) # 循环写,对csv中的每一行内容进行操作等
  18. file.close() #关
复制代码
同样的,养成with as的良好习惯,避免close操作的遗漏。
  1. # 基本逻辑都是:
  2. # 1,with操作打开文件,如果是读csv文件,就open+r;如果是写csv文件,就open+w,按照前面文件基本读写模式
  3. # 2,对打开的文件可操作对象进行转换(这样才方便使用对应csv对象中的实现方法)
  4. # 3,writer写对象就用写方法,reader读对象就用读方法
  5. # 4,读写完毕之后对于最初打开的文件可操作对象要关闭
  6. # 写:with打转写
  7. import csv
  8. with open("path_to_csv_to_write.csv","w") as file: #with打
  9.     csv_writer = csv.writer(file) #转
  10.     csv_writer.writerows([1个可迭代对象]) #写
  11. # 读:with打转读
  12. import csv
  13. with open("path_to_csv_to_read.csv","r") as file: #with打
  14.     csv_reader = csv.reader(file) #转
  15.     for row in csv_reader:
  16.         print(row) # 循环写,对csv中的每一行内容进行操作等
复制代码
我们来总结一下上面的内容:
**在Python中,文件读写是通过open()函数打开的文件对象完成的。使用with语句操作文件IO是个好习惯。
**文件基本操作是:with打写、with打读;
涉及csv模块的:with打转写、with打转读
假如是读的话建议是for循环读。

别的注意一下encoding参数,即读写的文件编码格式即可,
参考:https://docs.python.org/3/library/codecs.html

二,异常和异常处置惩罚:

要熟悉debug中各种常见的报错error:

这一部分主要是积累debug经验,以及本身严谨规范写代码中的操作。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表