资源简介 单元7 文件操作与异常处理课程名称 Python程序设计任务驱动式教程 章名 文件操作与异常处理教学内容 文件操作与异常处理 课时 6项目性质 □演示性 □验证性 □设计性 √综合性授课班级 授课日期 授课地点教学目标 了解路径、异常等基础知识 掌握打开与关闭文件 掌握读取与写入文件内容 掌握创建与操作文件、文件夹 掌握删除文件和文件夹 熟悉异常处理语句教学内容 打开与关闭文件 读取与写入文件内容 创建与操作文件、文件夹 删除文件和文件夹 异常处理语句教学重点 读取与写入文件内容教学难点 读取与写入文件内容教学准备 装有Python的计算机 教学课件PPT 教材:《Python程序设计任务驱动式教程(微课版)》作业设计17教学过程教学环节 教学内容与过程 (教学内容、教学方法、组织形式、教学手段)课前组织 做好上课前的各项准备工作(打开计算机、打开课件、打开软件、打开授课计划、教案等),吸引学生注意力。课程说明 【课前说明】 分别从路径、异常等知识点进行初步的了解。 【目的】 使学生从了解本节课的学习目标、学习重点、考评方式等方面明确课程学习的要求和目标。课程内容描述 7.1 打开与关闭文件 Python中,在使用内置文件对象时,首先需要使用内置的open()方法打开文件,并创建一个文件对象,然后通过该文件对象的方法进行一些操作。 7.1.1 使用open()方法打开文件 Python的open()方法用于打开一个文件,并返回文件对象,在对文件进行处理的过程中都需要使用到这个方法。如果该文件无法被打开,会抛出OSError异常。 open()方法将会返回一个文件对象。open()方法的常用形式是接收两个参数:文件名(filename)和模式(mode)。 调用该方法的基本语法格式如下。 file=open(filename[, mode[, buffering [, encoding=None]]]) 参数说明如下。 ① file:表示被创建的文件对象。 ② filename:用于指定包含待打开或待创建文件的文件路径(相对路径或绝对路径)与文件名称字符串值,需要使用单引号或双引号标注。如果待打开的文件和使用open()方法的程序文件位于同一个文件夹中,即两个文件存储位置相同时,可以直接写文件名,不需要指定文件路径,否则需要指定完整路径。 ③ mode:为可选参数,用于指定打开文件的模式,即描述文件如何使用,如只读、写入、追加等。r表示打开的文件只读;w表示文件只用于写(如果存在同名文件则将被删除);a表示在文件末尾追加文件内容,所写的任何数据都会被自动增加到文件末尾;r+表示文件同时用于读写。文件打开模式参数如电子活页7-1所示。这个参数是非强制的,默认文件访问模式为只读(r)。 ④ buffering:可选参数,用于指定读写文件的缓冲模式,取值为0表示不缓冲;取值为1表示缓冲;如果取值大于1,则表示缓冲区的大小。默认为缓冲模式。 ⑤ encoding:可选参数,用于指定文件的编码方式,默认使用GBK编码,如果需要指定其他编码方式,可以在打开文件时直接指定使用的编码方式。 open()方法用于打开一个文件时,指定打开文件的模式的常见状态如表所示。 指定打开文件的模式的常见状态 模式rr+ww+aa+读√√√√写√√√√√创建√√√√覆盖√√文件指针在开始位置√√√√文件指针在结尾位置√√以下演示了open()方法的多种使用方式。 (1)以默认方式打开一个文本文件。 >>>file=open('如何注册京东账号.txt') open()方法中只指定了文本文件名称,默认为文本文件模式(t)、默认文件访问模式为只读(r)、默认为缓冲模式、默认文件编码为GBK编码。 open('如何注册京东账号.txt')与open('如何注册京东账号.txt','r')的访问模式相同,都表示只读访问模式。 (2)以二进制形式打开非文本文件。 使用open()方法可以以二进制形式打开图片文件、音频文件、视频文件等非文本文件。 >>>file=open('hh.jpg','rb') 加上“b”表示以二进制形式打开非文本文件。 (3)打开文件时指定编码方式。 打开文件时添加“encoding='utf-8'”参数,指定编码方式为“utf-8”。 >>>file=open('如何注册京东账号.txt','r',encoding='utf-8') 7.1.2 使用close()方法关闭文件 Python中,使用open()方法打开文件后,需要及时关闭,避免对文件造成不必要的破坏。可以使用文件对象的close()方法实现关闭打开的文件。 使用close()方法的基本语法格式如下。 file.close() 其中,file为打开的文件对象。 调用close()方法时,先刷新缓冲区中还没有写入的内容,然后关闭文件,这样可以将没有写入文件的内容写入文件,在关闭文件后,便不能再进行写入操作了。 当处理完一个文件后,调用close()方法来关闭文件并释放系统的资源,如果尝试再次调用该文件,则会抛出异常。 例如: >>>file=open('如何注册京东账号.txt', 'r') >>>file.close() >>>file.read() 运行时会出现以下异常信息。 Traceback (most recent call last): File "", line 1, in ValueError: I/O operation on closed file. 7.1.3 打开文件时使用with语句 使用open()方法打开文件后,如果没有及时关闭文件可能会带来意想不到的问题。另外,如果在打开文件时抛出了异常,也会导致文件不能被及时关闭。为了更好地避免此类问题发生,可以使用Python提供的with语句,从而实现在处理文件时,无论是否抛出异常都能保证with语句执行完毕后关闭已经打开的文件。 使用open()方法打开文件时应用with语句的基本语法格式如下。 with open(filename[, mode[, buffering [, encoding=None]]]) as file: <语句体> 其中,file为文件对象,用于将打开文件的结果保存到该对象中,语句体是执行with语句后相关的一些操作语句。如果暂不指定任何语句,可以使用pass语句代替。 当处理一个文件对象时,使用with语句是非常好的方式。在处理结束后,它会自动正确关闭文件。而且其语句体写起来也比try-finally语句体要简短。 例如: >>>with open('如何注册京东账号.txt','r',encoding='utf-8') as file: pass >>>file.closed 运行结果如下。 True 【实例7-1】演示使用open()方法打开文件、使用close()方法关闭文件、使用with语句打开文件后自动关闭文件 实例7-1的代码如下所示。 file=open('如何注册京东账号.txt') file.close() with open('如何注册京东账号.txt','r',encoding='utf-8') as file: pass 7.2 读取与写入文件内容 Python中的文件对象提供了write()方法向文件中写入内容,也提供了readline()、readlines()、read()等多种读取文件内容的方法。 7.2.1 文件对象 使用open()方法打开文件,并创建文件(file)对象的代码如下。 file=open(filename[, mode[, buffering [, encoding=None]]]) file对象常用的方法如电子活页7-2所示。 7.2.2 移动文件的当前位置 Python提供了seek()方法将文件指针移动到指定位置。 seek()方法的基本语法格式如下。 file.seek(offset [, whence ] ) 其中,file表示已经打开的文件对象;offset用于指定移动的字符个数,计数的起始位置由可选参数whence指定;whence用于指定从什么位置开始计算,值为0表示从文件的开始位置开始计算,值为1表示从当前位置开始计算,值为2表示从文件末尾位置开始计算,默认值为0,即默认为从文件的开始位置开始计算。 使用seek()方法时,offset的值是按1个汉字占2个或3个字节(GBK编码1个汉字占2个字节,UTF-8编码1个汉字占3个字节),1个英文字母或半角数字占1个字节计算。这与read(size)方法按字符数量计算不同。 对于whence参数,如果在打开文件时没有使用二进制形式,那么只允许从文件开始位置开始计算相对位置(只会相对于文件起始位置进行定位),如果从文件末尾位置开始计算就会抛出异常。 以二进制形式打开文件时,使用文件对象的seek()方法改变文件的当前位置有多种方法。例如: seek(n,0):表示从起始位置即文件首行首字符开始移动n个字符。 seek(n,1):表示从当前位置往后移动n个字符。 seek(-n,2):表示从文件的结尾位置往前移动n个字符。 7.2.3 读取文件 Python中,使用open()方法打开一个文件后,可以读取该文件中的内容,读取文件内容的方式有多种。 1.使用readline()方法读取一行 Python中,文件对象提供了readline()方法用于每次逐行读取。readline()方法的基本语法格式如下。 file.readline() 其中file为打开的文件对象,打开文件时,需要指定打开模式为只读(r)或者读写(r+)。 【实例7-2】演示打开文本文件“如何注册京东账号.txt”后,读取第一行内容并输出 提示:文本文件“如何注册京东账号.txt”的初始内容如下。 如何注册京东账号? 若您还没有京东账号,请单击注册,详细操作步骤如下。 (1)打开京东首页,在右上方单击【免费注册】按钮。 (2)进入注册页面,请填写您的邮箱、手机号等信息完成注册。 (3)注册成功后,请完成账户安全验证来提高您的账户安全等级。 实例7-2的代码如下所示。 with open('如何注册京东账号.txt','r') as file: line = file.readline() print(line,end= "\n") # 输出一行内容 实例7-2的运行结果如下。 如何注册京东账号? 2.使用readlines()方法读取全部行 Python中,文件对象提供了readlines()方法用于每次读取全部行。readlines()方法的基本语法格式如下。 file.readlines() 其中,file为打开的文件对象,打开文件时,需要指定打开模式为只读(r)或者读写(r+)。 使用readlines()方法读取全部行时,返回的是一个字符串列表,每个元素为文件的一行内容。 【实例7-3】演示打开文本文件后,读取全部行的内容并输出 实例7-3的代码如下。 with open('如何注册京东账号.txt','r') as file: lines = file.readlines() print(lines) #输出全部行的内容 实例7-3的运行结果如下。 ['如何注册京东账号?\n', '若您还没有京东账号,请单击注册,详细操作步骤如下。 \n', '(1)打开京东首页,在右上方单击【免费注册】按钮。\n', '(2)进入注册页面,请填写您的邮箱、手机号等信息完成注册。\n', '(3)注册成功后,请完成账户安全验证来提高您的账户安全等级。\n'] 从上述运行结果可以看出readlines()方法的返回值为一个字符串列表。在这个字符串列表中,每个元素记录一行内容。如果文件比较大,使用这种方式输出读取的文件内容速度会很慢,这时可以将字符串列表的内容逐行输出。 3.使用read()方法读取指定个数的字符 Python中,文件对象提供了read()方法读取指定个数的字符,其基本语法格式如下。 file.read( [size] ) 其中,file为打开的文件对象,size为可选参数,用于指定要读取的字符个数,如果省略则一次性读取所有内容。打开文件时,需要指定打开模式为只读(r)或者读写(r+),否则会抛出异常。 (1)读取打开文件的全部内容。 【实例7-4】演示打开文本文件后,读取该文件的全部内容并输出 实例7-4的代码如下。 with open('如何注册京东账号.txt','r') as file: content = file.read() print(content) # 输出全部行的内容 实例7-4的运行结果如下。 如何注册京东账号? 若您还没有京东账号,请单击注册,详细操作步骤如下。 (1)打开京东首页,在右上方单击【免费注册】按钮。 (2)进入注册页面,请填写您的邮箱、手机号等信息完成注册。 (3)注册成功后,请完成账户安全验证来提高您的账户安全等级。 (2)从文件的开始位置读取指定数量的字符。 【实例7-5】演示打开文本文件后,读取该文件的前9个字符并输出 实例7-5的代码如下所示。 with open('如何注册京东账号.txt','r') as file: content = file.read(9) print(content) 实例7-5的运行结果如下。 如何注册京东账号? (3)从文件的指定位置开始读取指定数量的字符。 使用read([size])方法读取文件内容时,默认是从文件的开始位置读取的。如果想要读取中间部分的内容,可以先使用文件对象的seek()方法将文件指针移动到指定位置,然后使用read([size])方法读取指定数量的字符。 【实例7-6】演示seek()、tell()和read()方法的联合使用 实例7-6的代码如下所示。 with open('如何注册京东账号.txt','r') as file: print("1-打开文件时,当前位置为:",file.tell()) content1 = file.read(9) print("输出第1次读取的内容:",content1) print("2-第1次读取指定数量的字符后,当前位置为:", file.tell()) file.seek(40) print("3-显式改变当前位置后,当前位置为:", file.tell()) content2 = file.read(5) print("输出第2次读取的内容:",content2) print("4-第2次读取指定数量的字符后,当前位置为:", file.tell()) 实例7-6的运行结果如下。 1-打开文件时,当前位置为:0 输出第1次读取的内容:如何注册京东账号? 2-第1次读取指定数量的字符后,当前位置为:18 3-显式改变当前位置后,当前位置为:40 输出第2次读取的内容:请单击注册 4-第2次读取指定数量的字符后,当前位置为:50 从运行结果可以看出:调用open()方法打开文件时,当前位置为0,调用read(9)方法,读取并输出第1行的9个字符(18字节),当前位置为18;然后将文件指针从文件开始位置(相对起始位置)向后移动20个字符(40字节),当前位置为40;再读取并输出5个字符(10字节),当前位置为50。 实例7-6中使用了文件对象的tell()方法,该方法返回文件对象当前所处的位置,它从文件开始位置开始计算字节数。 7.2.4 向文件中写入内容 Python的文件对象提供了write()方法,可以向文件中写入内容。write()方法的基本语法格式如下。 file.write(string) 其中,file为使用open()方法打开的文件对象;string表示待写入的字符串格式的内容。打开文件时,需要指定打开模式为可写(w)或者追加(a),否则会抛出异常。 file.write(string)将string写入文件,然后返回写入的字符数。如果要写入的内容不是字符串类型,那么需要先进行转换,例如数值可以使用str()函数转换为字符串。 【实例7-7】演示使用open()方法创建文件,使用write()方法向文件中写入内容,然后读取并输出文件内容 实例7-7的代码如下所示。 content='Bright sunshine, full of vitality and all things renewed' file= open("expectation.txt", "w") #打开一个文件 num = file.write(content) #写入内容 print(num) file.close() #关闭打开的文件 file= open("expectation.txt", "r") #打开一个文件 text=file.read() print(text) 实例7-7的运行结果如下。 56 Bright sunshine, full of vitality and all things renewed 下面针对文本文件expectation.txt应用seek()方法改变当前位置,并观察当前位置的变化。 例如: >>>file = open('expectation.txt', 'rb+') >>>file.seek(5) #当前位置移动到文件的第6个字符 5 >>>file.read(1).decode() 't' >>file.seek(-3, 2) #当前位置移动到文件的倒数第3个字符 53 >>>file.read(1).decode() 'w' >>>file.close() 【任务7-1】打开并读取文件的全部行 【任务描述】 (1)在PyCharm集成开发环境中创建项目Unit07。 (2)在项目Unit07中创建Python程序文件7-1.py。 (3)以只读方式打开当前工作文件夹中的文本文件:如何注册京东账号.txt,然后读取并输出该文件的全部行。 【任务实施】 1.创建PyCharm项目Unit07 成功启动PyCharm后,在指定位置“D:\PycharmProject\”创建PyCharm项目Unit07。 2.创建Python程序文件7-1.py 在PyCharm项目Unit07中新建Python程序文件7-1.py,同时PyCharm主窗口显示程序文件7-1.py的代码编辑窗口,在该程序文件的代码编辑窗口自动添加了模板内容。 3.编写Python程序代码 在新建文件7-1.py的代码编辑窗口已有模板注释内容下面输入程序代码,程序文件7-1.py的代码如下所示。 def readFile(): objFile=open("D:\\PycharmProject\\Unit07\\如何注册京东账号.txt","r") for txtLine in objFile.readlines(): print(txtLine,end="") objFile.close() try: readFile() except Exception as error: print(error) 单击工具栏中的【保存】按钮,保存程序文件7-1.py。 4.运行Python程序 在PyCharm主窗口选择【Run】菜单,在弹出的下拉菜单中选择【Run】。在弹出的【Run】对话框中选择“7-1”选项,程序文件7-1.py开始运行。程序文件7-1.py的运行结果如下所示。 如何注册京东账号? 若您还没有京东账号,请单击注册,详细操作步骤如下: (1)打开京东首页,在右上方单击【免费注册】按钮; (2)进入注册页面,请填写您的邮箱、手机号等信息完成注册; (3)注册成功后,请完成账户安全验证来提高您的账户安全等级。 【任务7-2】实现文件内容的写入与读取 【任务描述】 (1)在项目Unit07中创建Python程序文件7-2.py。 (2)使用两种方法将图书数据写入当前工作文件夹的myBook.txt文件中。 (3)使用两种方法从myBook.txt文件中读取全部行并输出。 【任务实施】 1.创建Python程序文件7-2.py 在PyCharm项目Unit07中新建Python程序文件7-2.py,同时PyCharm主窗口显示程序文件7-2.py的代码编辑窗口,在该程序文件的代码编辑窗口自动添加了模板内容。 2.编写Python程序代码 在新建文件7-2.py的代码编辑窗口已有模板注释内容下面输入程序代码,程序文件7-2.py的代码如电子活页7-3所示。 单击工具栏中的【保存】按钮,保存程序文件7-2.py。 3.运行Python程序 在PyCharm主窗口选择【Run】菜单,在弹出的下拉菜单中选择【Run】。在弹出的【Run】对话框中选择“7-2”选项,程序文件7-2.py开始运行。程序文件7-2.py的运行结果如图所示。 程序文件7-2.py的运行结果 【任务7-3】以二进制形式打开文件并读取其内容 【任务描述】 (1)在项目Unit07中创建Python程序文件7-3.py。 (2)自定义函数readFile(),该函数以二进制形式只读模式“rb”打开文本文件expectation.txt,然后读取该文件的内容,并使用函数decode()将bytes对象转换为文字字符串。 (3)调用自定义函数readFile(),并以文字形式输出文件expectation.txt的内容。 【任务实施】 在PyCharm项目Unit07中创建Python程序文件7-3.py。在程序文件7-3.py中编写程序代码,实现所需功能,程序文件7-3.py的代码如下所示。 fileName=r"D:\PycharmProject\Unit07\expectation.txt" def readFile(fileName): objFile = open(fileName,"rb") text=objFile.read() strText=text.decode(encoding="utf-8", errors="strict") objFile.close() return strText try: print(readFile(fileName)) except Exception as error: print(error) 程序文件7-3.py运行结果的部分内容如下。 Bright sunshine, full of vitality and all things renewed 二进制文件不存在编码的问题,只有文本文件才有编码问题。使用open()方法以二进制形式打开文件时,不能通过encoding参数指定编码方式,否则会出现错误。二进制文件是字节流,不能使用readline()、readlines()函数读取文件内容,一般使用read()函数读取文件内容,使用write()函数向文件写入内容。 【任务7-4】通过移动文件指针的方法读取指定字符 【任务描述】 (1)在项目Unit07中创建Python程序文件7-4.py。 (2)以二进制形式打开文本文件expectation.txt。 (3)结合移动文件指针的方法seek()从文本文件expectation.txt中多次读取指定数量的字符,并使用函数decode()将bytes对象转换为文字字符串输出。 【任务实施】 在PyCharm项目Unit07中创建Python程序文件7-4.py。在程序文件7-4.py中编写程序代码,实现所需功能,程序文件7-4.py的代码如电子活页7-4所示。 程序文件7-4.py中调用open()函数时,使用了“rb”模式,这表明采用二进制形式读取文本文件,此时文件对象的read()方法返回的是bytes对象,调用bytes对象的decode()方法将它恢复成字符串。如果所读取的文件是以UTF-8的格式保存的,需要在使用decode()方法恢复文字字符串时显式指定使用UTF-8字符集。decode()方法的另一个参数“errors”用于指定错误处理方式,其可选择的值是:strict,遇到非法字符就抛出异常;ignore,忽略非法字符;replace,用“?”替换非法字符;xmlcharrefreplace,使用xml的字符引用。errors参数的默认值为strict。 程序文件7-4.py的运行结果如下所示。 当前文件指针的位置1:0 第1次读取的6个字符:Bright 当前文件指针的位置2:7 第2次读取的8个字符:sunshine 指针移动后文件指针的位置3:15 第3次读取的字符:full of vitality and all things renewed 指针移动后文件指针的位置4:56 7.3 创建与操作文件、文件夹 文件夹也称为目录,用于分层存储文件。通过文件夹可以分门别类地存放文件,也可以通过文件夹快速找到想要的文件。Python中需要使用内置os模块和os.path模块中的方法操作文件夹。 Python中,os模块和os.path模块主要用于对文件夹和文件进行操作,常见的文件夹操作主要有判断文件夹是否存在、创建文件夹、删除文件夹和遍历文件夹等,本节针对文件夹的操作都是在Windows操作系统中执行。 7.3.1 创建文件夹 Python中,os模块提供了创建文件夹的方法。 1.创建一级文件夹 创建一级文件夹是指一次只能创建一个文件夹,在Python中可以使用os模块提供的mkdir()方法实现。通过该方法创建指定路径中的最后一级文件夹,如果该文件夹所在的上一级文件夹不存在,则会抛出FileNotFoundError异常。 mkdir()方法的基本语法格式如下。 os.mkdir( path ) 其中,path用于指定要创建的文件夹,可以使用相对路径,也可以使用绝对路径。 例如,在Windows操作系统中创建一个文件夹“D:\PycharmProject\Test07\test”,可以使用以下代码。 >>>import os >>>os.mkdir(r"D:\PycharmProject\Test07\test") 运行以上代码后,将在文件夹“D:\PycharmProject\ Test07”下创建一个新的文件夹test,如图所示。 创建文件夹test 如果创建文件夹时,文件夹test已经存在了,将抛出FileExistsError异常,将上面的代码再运行一次,将出现以下异常信息。 Traceback (most recent call last): File "", line 1, in FileExistsError: [WinError 183] 当文件已存在时,无法创建该文件。: 'D:\\PycharmProject\\Test07\\test' 如果创建的文件夹有多级父文件夹,待创建文件夹的父文件夹不存在,则会抛出FileNotFoundError异常。 例如: >>>import os >>>os.mkdir(r"D:\PycharmProject\Test08\test") 运行上面的代码,会出现以下异常信息。 Traceback (most recent call last): File "", line 1, in FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'D:\\PycharmProject\\Test08\\test' 创建文件夹时,为了保证不出现重复创建文件夹的问题,可以在创建文件夹前使用exists()方法判断指定的文件夹是否存在,根据判断结果再做出合理的操作。 例如: >>>import os >>>if not os.path.exists((r"D:\PycharmProject\Test07\test")): os.mkdir(r"D:\PycharmProject\Test07\test") 运行上面的代码,如果文件夹test已经存在,if语句的条件表达式值为False,则不再执行创建文件夹test的语句,也不会抛出FileExistsError异常。 2.创建多级文件夹 使用mkdir()方法一次只能创建一级文件夹。如果需要一次创建多级文件夹,可以使用os模块提供的makedirs()方法,该方法会采用递归的方式逐级创建指定的多级文件夹。makedirs()方法的基本语法格式如下。 os. makedirs(name) 其中,name用于指定要创建的多级文件夹,可以使用相对路径,也可以使用绝对路径。例如,在Windows操作系统中,需要在文件夹“D:\PycharmProject\Test07”中再创建子文件夹01,再在子文件夹01中创建下级子文件夹0101,可以通过以下代码实现。 >>>import os >>>os.makedirs(r"D:\PycharmProject\Test07\01\0101") 运行上面的代码后,将创建图所示的两级子文件夹。 创建的两级子文件夹 7.3.2 针对文件夹的操作 1.判断文件夹是否存在 Python中,判断文件夹是否存在,可以使用os.path模块提供的exists()方法实现。exists()方法的基本语法格式如下。 os.path.exists(path) 其中,path表示待判断的文件夹的路径,可以是相对路径,也可以是绝对路径。如果指定路径中文件夹存在,则返回True,否则返回False。 例如,要判断文件夹“D:\PycharmProject\Test07”是否存在,可以使用以下代码。 >>>import os >>>print(os.path.exists(r"D:\PycharmProject\Test07")) 运行上面两行代码,如果文件夹Test07存在,则返回True,否则返回False。 2.遍历文件夹 遍历是指对指定文件夹下的全部子文件夹和文件浏览一遍。Python中,os模块的walk()方法可以实现遍历文件夹的功能。walk()方法的基本语法格式如下。 os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]]) 其中,top用于指定要遍历的根文件夹。topdown为可选参数,用于指定遍历的顺序,其默认值为True。如果其值为True,则表示自上而下进行遍历(先遍历根文件夹);如果其值为False,则表示自下而上进行遍历(先遍历最后一级子文件夹)。onerror为可选参数,用于指定错误处理方式,默认为忽略,如果不想忽略也可以指定一个错误处理函数。followlinks为可选参数,默认情况下,walk()方法不会向下转换成解析到文件夹符号链接,将该参数设置为True,表示用于指定在支持的操作系统上访问由符号链接指向的文件夹。 walk()方法返回一个包括3个元素(dirpath、dirnames、filenames)的元组生成器对象。其中dirpath表示当前遍历的路径,是一个字符串;dirnames表示当前路径下包含的子文件夹,是一个列表;filenames表示当前路径下包含的文件,也是一个列表。 【实例7-8】演示使用walk()方法遍历文件夹“D:\PycharmProject\Test07” 实例7-8的代码如下所示。 import os tuple=os.walk(r"D:\PycharmProject\Test07") for item in tuple: print(item) 如果在文件夹“D:\PycharmProject\Test07”中包括下图所示的子文件夹和文件,运行上面的代码,将显示如下结果。 ('D:\\PycharmProject\\Test07', ['demo', 'test'], ['message.txt', 'test7-1.py']) ('D:\\PycharmProject\\Test07\\demo', [], ['message.txt']) ('D:\\PycharmProject\\Test07\\test', [], []) 文件夹Test07中包含的子文件夹与文件 3.重命名文件夹 os模块提供了重命名文件夹的方法rename(),该方法的基本语法格式如下。 os.rename(src, dst ) 如果参数src、dst指定的是文件夹,则重命名文件夹。其中,src用于指定要进行重命名的文件夹名称;dst用于指定重命名后的文件夹名称。 在进行重命名文件夹操作时,如果指定的文件夹不存在,将会抛出FileNotFoundError异常,所以在进行重命名文件夹操作时,先使用os.path模块中的exists()方法判断文件夹是否存在,只有文件夹存在时才可以进行。 例如,要将当前工作文件夹中的子文件夹名称“demo”修改为“demo07”,可以使用下面的代码。 >>>import os >>>os.rename("demo","demo07") 运行上面的代码,如果当前工作文件夹中的子文件夹名称“demo”存在,则会完成子文件夹的重命名操作,否则将抛出异常。 使用rename()方法,只能修改路径中最后一级的子文件夹名称,否则将抛出异常。 7.3.3 创建文件 调用open()方法时,指定mode模式参数值为w、w+、a、a+时,当要打开的文件不存在时,就会创建一个新文件。 例如,使用以下代码在当前工作文件夹中创建一个名称为“expectation.txt”的文本文件。 >>>file=open('expectation.txt','w') >>>file.close() 以上代码成功执行时,会在当前工作文件夹中创建一个文本文件expectation.txt。 7.3.4 针对文件的操作 1.判断文件是否存在 Python中,判断文件是否存在,也可以使用os.path模块提供的exists()方法实现。exists()方法的基本语法格式如下。 os.path.exists(path) 其中,path表示待判断的文件,path中包含有路径,可以是相对路径,也可以是绝对路径。如果指定路径中的文件存在,则返回True,否则返回False。 例如,要判断指定的文件“D:\PycharmProject\Test07\message.txt”是否存在,可以使用以下代码。 >>>import os >>>print(os.path.exists(r"D:\PycharmProject\Test07\message.txt ")) 运行上面两行代码,如果指定文件夹Test07中的文件message.txt存在,则返回True,否则返回False。 2.获取文件的基本信息 在计算机中创建文件后,该文件本身就会包含一些有用的信息,例如,文件大小、文件的最后一次访问时间、文件的最后一次修改时间,通过os模块的stat()方法可以获取文件的这些信息。stat()方法的基本语法格式如下。 os.stat(path) 其中,path为要获取文件信息的文件路径,可以是相对路径,也可以是绝对路径。 stat()方法的返回值是一个对象,该对象包括的属性有:st_mode(保护模式)、st_ino(索引值)、st_nlink(被连接数目)、st_size(文件大小,单位为字节)、st_mtime(最后一次修改时间)、st_dev(设备名)、st_uid(用户ID)、st_gid(组ID)、st_atime(最后一次访问时间)、st_ctime(最后一次状态变化的时间,Windows中返回的是文件的创建时间)。 例如,要获取文本文件message.txt的文件大小信息,代码如下。 >>>import os >>>fileInfo=os.stat("message.txt") >>>print("文件大小:",fileInfo.st_size,"字节" ) 运行结果如下。 文件大小:26 字节 3.重命名文件 os模块提供了重命名文件的方法rename(),该方法的基本语法格式如下。 os.rename(src, dst ) 如果参数src、dst指定的是文件,则重命名文件。其中,src用于指定要进行重命名的文件名称;dst用于指定重命名后的文件名称。 在进行重命名文件操作时,如果指定的文件不存在,将会抛出FileNotFoundError异常,所以在进行重命名文件操作时,先使用os.path模块中的exists()方法判断文件是否存在,只有文件存在时才可以进行。 例如,要将当前工作文件夹中的文件名称“message.txt”修改为“message07.txt”,可以使用下面的代码。 >>>import os >>>os.rename(r"D:\PycharmProject\Test07\message.txt",r"D:\PycharmProject\Test07\message07.txt") 运行上面的代码,如果在文件夹“D:\PycharmProject\Test07”中存在文件message.txt,则会完成文件message.txt的重命名操作,否则将抛出异常。 【任务7-5】以多种方式创建文件夹与文件 【任务描述】 (1)在项目Unit07中创建Python程序文件7-5.py。 (2)使用os模块中的mkdir()方法、makedirs()方法分别创建多个文件夹:demo、text、01、02。 (3)在文件夹“D:\PycharmProject\Unit07\demo”中创建文本文件test1.txt。 (4)在文件夹“D:\PycharmProject\Unit07\demo\text\02”中创建文本文件test2.txt。 建立的文件夹demo及其子文件夹和文本文件如图所示。 建立的文件夹demo及其子文件夹和文本文件 【任务实施】 在PyCharm项目Unit07中创建Python程序文件7-5.py。在程序文件7-5.py中编写程序代码,实现所需功能,程序文件7-5.py的代码如电子活页7-5所示。 如果文件夹demo及其子文件夹和文本文件还没有建立,程序文件7-5.py的运行结果如下。 当前文件所在的路径为:D:\PycharmProject\Unit07 文件myBook.txt所在的完整路径为:D:\PycharmProject\Unit07\myBook.txt 成功创建文件夹demo 成功创建文本文件test1.txt 成功创建文件夹text\01 成功创建文件夹text\02 成功创建文本文件test2.txt 如果文件夹demo及其子文件夹和文本文件已经建立完成,再一次运行程序7-5.py,则其运行结果如下。 当前文件所在的路径为:D:\PycharmProject\Unit07 文件myBook.txt所在的完整路径为:D:\PycharmProject\Unit07\myBook.txt 文件夹demo已经存在 文本文件test1.txt已经存在 文件夹text\01已经存在 文件夹text\02已经存在 文本文件test2.txt已经存在 7.4 删除文件和文件夹 Python中的os模块提供了多种删除文件和文件夹的方法。 7.4.1 删除文件 Python中,内置的os模块提供了删除文件的方法remove(),该方法的基本语法格式如下。 os.remove( path ) 其中,path为待删除文件所在的路径,可以使用相对路径,也可以使用绝对路径。 例如,要删除指定文件夹中的文件message.txt,可以使用下面的代码。 >>>import os >>>os.remove(r"D:\PycharmProject\Test07\message.txt ") 运行上面的代码后,如果在文件夹“D:\PycharmProject\Test07”中存在文本文件message.txt,则可以将其删除,否则会出现以下异常信息。 Traceback (most recent call last): File "", line 1, in FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'D:\\PycharmProject\\Test07\\message.txt ' 为了解决删除不存在的文件时出现异常的问题,可以在删除文件时,先使用os.path.exists()方法判断待删除文件是否存在,只有文件存在时才执行删除操作。 7.4.2 删除文件夹 1.删除空文件夹 删除空文件夹可以使用os模块提供的rmdir()方法实现,通过rmdir()方法删除文件夹,只有当待删除的文件夹为空时才能完成。rmdir()方法的基本语法格式如下。 os.rmdir( path )其中,path为待删除的文件夹的路径,可以使用相对路径,也可以使用绝对路径。 例如,删除前面创建的文件夹0101,可以使用下面的代码。 >>>import os >>>os.rmdir(r"D:\PycharmProject\Test07\01\0101") 运行上面的代码后,“D:\PycharmProject\Test07\01”文件夹中的子文件夹0101将被删除。 如果待删除的文件夹不存在,将抛出异常。 例如,子文件夹0101被删除后,如果再一次运行上述代码,则会出现以下异常信息。 Traceback (most recent call last): File "", line 1, in FileNotFoundError: [WinError 2] 系统找不到指定的文件。: 'D:\\PycharmProject\\Test07\\01\\0101' 因此,在执行rmdir()方法删除指定文件夹前,应先使用os.path.exists()方法判断该待删除的文件夹是否存在,如果存在则删除。 2.删除非空文件夹 使用rmdir()方法只能删除空文件夹,如果想要删除非空文件夹,可以使用Python内置的标准模块shutil中的rmtree()方法实现。 例如,在文件夹01中有一个子文件夹0101和一个文本文件message.txt,如果需要删除该非空文件夹01,可以使用下面的代码。 >>>import shutil >>>shutil.rmtree(r"D:\PycharmProject\Test07\01") 运行上面的代码,则会直接将文件夹01中的子文件夹0101和文本文件message.txt都予以 删除。 【任务7-6】以多种方式删除文件夹与文件 【任务描述】 (1)在项目Unit07中创建Python程序文件7-6.py。 (2)使用os模块中的remove()方法删除文本文件test1.txt。 (3)使用shutil模块中的rmtree()方法删除文件夹02及该文件夹中存放的文件test2.txt。 (4)使用os模块中的rmdir()方法删除文件夹01。 (5)使用shutil模块中的rmtree()方法删除文件夹demo及该文件夹中存放的文件test1.txt。 【任务实施】 在PyCharm项目Unit07中创建Python程序文件7-6.py。在程序文件7-6.py中编写程序代码,实现所需功能,程序文件7-6.py的代码如电子活页7-6所示。 如果文件夹demo及其子文件夹和文本文件还没有建立,参见图7-5所示在指定位置分别创建文件夹demo、text、01、02,然后运行程序文件7-6.py。 程序文件7-6.py的运行结果如下。 成功删除文件夹D:\PycharmProject\Unit07\demo中的文件test1.txt 成功删除文件夹02及其文件 成功删除文件夹01 成功删除文件夹demo及其文件 【任务7-7】实现文件复制、重命名、信息输出功能 【任务描述】 (1)在项目Unit07中创建Python程序文件7-7.py。 (2)自定义文件复制函数,并调用该函数实现文件复制功能。 (3)自定义文件重命名函数,并调用该函数实现文件重命名功能。 (4)自定义文件信息输出函数,并调用该函数实现文件信息输出功能。 (5)遍历各级文件夹,输出当前遍历的路径、当前路径下包含的子文件夹和文件。 【任务实施】 在PyCharm项目Unit07中创建Python程序文件7-7.py。在程序文件7-7.py中编写程序代码,实现所需功能,程序文件7-7.py的代码如电子活页7-7所示。 程序文件7-7.py的运行结果如下。 文件 D:\PycharmProject\Unit07\如何注册京东账号.txt 不存在,接下来进行文件创建 输出文件 D:\PycharmProjects\demo\text\01\message.txt 的相关信息 文件完整路径:D:\PycharmProjects\demo\text\01\message.txt 文件大小:246 文件属性:32 最后一次修改时间:2020年04月15日 18:41:45 文件夹遍历返回信息如下: ('D:\\PycharmProject\\Unit07\\demo', ['text'], []) ('D:\\PycharmProject\\Unit07\\demo\\text', ['01', '02'], []) ('D:\\PycharmProject\\Unit07\\demo\\text\\01', [], []) ('D:\\PycharmProject\\Unit07\\demo\\text\\02', [], []) 7.5 异常处理语句 Python有两种错误很容易辨认:语法错误和异常。Python的assert语句用于判断一个表达式是否成立,在表达式条件的值为False的时候触发异常,assert语句已在单元4介绍过,这里不赘述。 7.5.1 try…except语句 Python中,可以使用try…except语句捕获并处理异常。使用该语句时,把可能会产生异常的代码放在try语句块1中,把处理结果放在except语句块2中。这样,当try语句块1中的代码出现错误,就会执行except语句块2中的代码;如果try语句块1中的代码没有错误,那么except语句块2将不会执行。 该语句的基本语法格式如下。 try: <语句块1> except [异常类型名称 [as alias]]: <语句块2> 其中,语句块1表示可能会出现错误的代码块。异常类型名称为可选参数,用于指定要捕获的异常类型,如果在其右侧加上“as alias”,则表示为当前的异常指定一个别名,通过该别名可以记录异常的具体内容。语句块2表示进行异常处理的代码块,可以输出提示信息,也可以通过别名输出异常的具体内容。 其结构与执行流程如图所示。 try…except语句的结构与执行流程 在使用try…except语句捕获异常时,如果在except后面不指定异常名称,则表示捕获全部异常。 【实例7-9】演示try…except语句的应用 实例7-9的代码如下所示。 try: num = eval(input("请输入数字:")) print(num**2) except: print("所输入的不是数字") 【实例7-10】演示使用try…except语句限制用户输入一个数字 实例7-10的代码如下所示。 while True: try: num = int(input("请输入一个数字:")) print("所输入的数字为:",num) except ValueError: print("所输入的不是数字,请再次尝试输入!") 实例7-10的代码运行时,try…except语句按照以下方式工作。 执行try子句(在关键字try和关键字except之间的语句)。如果没有异常发生,忽略except子句,try子句执行后结束。 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和except之后的异常名称相符,那么对应的except子句将被执行。 处理程序将只针对对应的try子句中的异常进行处理,而不会处理其他的try子句的处理程序中的异常。 【实例7-11】演示使用一个try语句包含多个except子句,分别来处理不同异常的情形 实例7-11的代码如下所示。 import sys try: file = open("如何注册京东账号.txt") line = file.readline() print(line) num = int(line.strip()) print(num) except OSError as err: print("操作系统错误: {0}".format(err)) except ValueError: print("无法将数据转换为整数") except: print("意外错误:", sys.exc_info()[0]) raise 实例7-11的运行结果如下。 如何注册京东账号? 无法将数据转换为整数 实例7-11中的一个try语句包含多个except子句,分别来处理不同的特定的异常,但最多只有一个except子句会被执行。 最后一个except子句可以忽略异常的名称,它将被当作通配符使用,可以使用这种方法输出错误信息。 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try。 另外,一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如: except(RuntimeError, TypeError, NameError): pass 7.5.2 try…except…else语句 Python中,try…except语句还有一个可选的else子句,用于指定当try语句块没有发现异常时要执行的语句块。如果使用else子句,那么必须将其放在所有的except子句之后。else子句将在try子句没有发生任何异常的时候执行,如果try子句中出现异常,则else子句不被执行。 其结构与执行流程如图所示。 try…except…else语句的结构与执行流程 以下实例在try语句中判断文件是否可以打开,如果能正常打开文件,没有发生异常则执行else部分的语句,读取文件内容。 【实例7-12】演示try…except…else语句的用法 实例7-12的代码如下所示。 arg="如何注册京东账号.txt" try: file = open(arg, "r") except IOError: print("cannot open", arg) else: print("文件“",arg, "”中的内容共有", len(file.readlines()), "行") file.close() 实例7-12的运行结果如下。 文件“ 如何注册京东账号.txt ”中的内容共有 5 行 使用else子句比把所有的语句都放在try子句里面要好,这样可以避免一些意想不到而except子句又无法捕获的异常。 异常处理并不仅仅处理那些直接发生在try子句中的异常,还能处理子句中调用的函数(甚至是间接调用的函数)中抛出的异常。 7.5.3 try…except…finally语句 完整的异常处理语句应该包括finally代码块,通常情况下,无论程序是否发生异常,finally代码块都将执行。 try: <语句块1> except [异常类型名称 [as alias]]: <语句块2> else: <语句块3> #不发生异常时执行 finally <语句块4> #最终会执行 其结构与执行流程如图所示。 try…except…finally语句的结构与执行流程 try…except…finally语句比try…except语句多了一个finally代码块,如果程序中有一些在任何情形下都必须执行的代码,那么就可以将它们放在finally子句的代码块位置。 无论是否引发了异常,finally子句都可以执行,例如分配了有限的资源,则应将释放这些资源的代码放置在finally子句的代码块位置。 【实例7-13】演示try…except…finally语句的用法 实例7-13的代码如下所示。 import os try: arg = "如何注册京东账号.txt" assert os.path.exists(arg),"拟打开的文件“"+arg+"”不存在" except AssertionError as error1: print(error1) else: try: with open(arg) as file: data = file.read(9) print(data) except FileNotFoundError as error2: print(error2) finally: print("拟打开的文件的名称为:",arg) 实例7-13的运行结果如下。 如何注册京东账号? 拟打开的文件的名称为:如何注册京东账号.txt 实例7-13中finally子句无论异常是否发生都会执行。 7.5.4 使用raise语句抛出异常 Python中,如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用raise语句在函数或方法中抛出一个指定的异常。 raise语句的基本语法格式如下。 raise [ExceptionName [, (reason)]] 其中,ExceptionName为可选参数,用于指定抛出的异常名称和异常信息的相关描述。如果省略该参数,就会把当前的错误原样抛出。参数reason也可以省略,如果省略,则在抛出异常时,不附带任何描述信息。 使用raise语句触发异常如图所示。 使用raise语句触发异常 以下代码如果x大于5就触发异常。 x = 10 if x > 5: raise Exception("x不能大于5。x的值为:{}".format(x)) 运行以上代码会触发异常出现以下信息。 Traceback (most recent call last): File "", line 2, in Exception: x不能大于5。x的值为:10 raise语句唯一的一个参数指定了要被抛出的异常,它必须是一个异常的实例或者是异常的类(也就是Exception的子类)。 如果只想知道是否抛出了一个异常,而并不想去处理它,那么一个简单的raise语句就可以再次把异常抛出。总结评价 本单元主要学习打开与关闭文件,读取与写入文件内容,创建与操作文件、文件夹,删除文件和文件夹,异常处理语句。 展开更多...... 收起↑ 资源预览