python从入门到精通(九):python文件操作和目录管理

python数据分析和可视化基础

第二十七章:python文件操作

(一)python文件操作学习目标

目标

  • 文件的概念
  • 文件的基本操作
  • 文件/文件夹的常用操作
  • 文本文件的编码方式

(二)文件的概念

文件的概念和作用

计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据。长期存储设备包括:硬盘、U盘、移动硬盘、光盘…
文件的作用是将数据长期保存下来,在需要的时候使用
在这里插入图片描述
文件的存储方式
在计算机中,文件是以二进制的方式保存在磁盘上的

文本文件和二进制文件

文本文件

  • 可以使用文本编辑软件查看
  • 本质上还是二进制文件
  • 例如:python 的源程序

二进制文件

  • 保存的内容 不是给人直接阅读的,而是 提供给其他软件使用的
  • 例如:图片文件、音频文件、视频文件等等
  • 二进制文件不能使用文本编辑软件 查看

(三)文件的基本操作

3.1操作文件的套路

在 计算机 中要操作文件的套路非常固定,一共包含三个步骤:

  • 打开文件

  • 读、写文件

    • 读 将文件内容读入内存
    • 写 将内存内容写入文件
  1. 关闭文件
3.2 操作文件的函数/方法

在Python中要操作文件需要记住1个函数和3个方法
在这里插入图片描述

open 函数负责打开文件,并且返回文件对象
read/write/close 三个方法都需要通过文件对象来调用
3.2.1 open方法打开文件

open : 函数的第一个参数是要打开的文件名(文件名区分大小写)
。如果文件 存在,返回 文件操作对象
。如果文件 不存在,会 抛出异常

f = open(‘test.txt’)   # 一般配合打开方式使用  例如 w
完整的语法格式为:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

#file 包含文件名的字符串,可以是绝对路径,可以是相对路径。
#mode 一个可选字符串,用于指定打开文件的模式。默认值 r 表示文本读。
#encoding 文本模式下指定文件的字符编码
3.2.2 write方法写入文件

write:方法负责 写入文件

#写入文件
f = open("test.txt","w") #打开文件,w模式(写模式),文件不存在就新建
f.write("hello world,I am here!")   #将字符串写入文件中
f.close()   #关闭文件

3.2.3 read方法打开文件

read :方法可以一次性 读入返回 文件的 所有内容

#读:read方法,默认读取全部,(5)读取指定的字符,开始时定位在文件头部,每执行一次向后移动指定字符数
f = open("test.txt","r")
text = f.read(5) #一次读五个字符
print(text)
print('-'*30)
text = f.read()   #读取全部
print(text)
f.close()

3.2.4 close方法打开文件

close:方法负责 关闭文件

f.close()
如果 忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问
注意:方法执行后,会把 `文件指针` 移动到 `文件的末尾`
# 1.打开文件
file = open("1.py",encoding="utf-8")

# 2.读取文件
text = file.read()
print(text)

# 3.关闭文件
file.close()

提示:
在开发中,通常会先编写 打开 和 关闭 的代码,再编写中间针对文件的 读/写 操作!

3.2.4 文件指针(知道)

文件指针 标记 从哪个位置开始读取数据
第一次打开 文件时,通常 文件指针会指向文件的开始位置
当执行了 read 方法后,文件指针会移动到 读取内容的末尾.
默认情况下会移动到 文件末尾

思考:
如果执行了一次 read 方法,读取了所有内容,那么再次调用read 方法,还能够获得到内容吗?
答案: 不能
第一次读取之后,文件指针移动到了文件末尾,再次调用不会读取到任何的内容

# 1.打开文件
file = open("1.py",encoding="utf-8")
# 2.读取文件
text = file.read()
print(text)
print(len(text))
print("_" * 50)
text = file.read()  # 再次调用不会读取到任何的内容
print(text)
print(len(text))  #长度为0
# 3.关闭文件
file.close()
907
__________________________________________________

0
3.2.5 打开文件的方式

open 函数默认以 只读方式 打开文件,并且返回文件对象
语法如下:

f = open("文件名","访问方式")
所有以 r 开头的,如果文件不存在,则报错,不会新建文件;文件指针都会放在文件的开头;
所有以 w 开头的,如果文件不存在,则自动创建;文件指针都会放在文件的开头;每次执行该函数时会覆盖掉源文件
所有以 a 开头的,如果文件不存在,则自动创建;文件指针会放在文件的末尾用于附加数据,不会覆盖数据

在这里插入图片描述

# 1.打开文件
file = open("1.py",'w')
# 写入文件
file.write("hello world")
print 
# 关闭文件
file.close()

提示
频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以 只读、只写 的方式来操作文件

(四)按行读取文件内容

read 方法默认会把文件的 所有内容 一次性读取到内存
如果文件太大,对内存的占用会非常严重

4.1 readiine 一次只读一行内容

readline 方法可以一次读取一行内容方法执行后,会把文件指针移动到下一行,准备再次读取
读取大文件的正确姿势

# 打开文件
file = open("4.py")
while True:
    # 读取一行内容
    text = file.readline() #读取一行内容 文件指针 移动到下一行
    # 判断是否读到内容
    if not text:
        break
# 每读取一行的末尾已经有了一个\n
    print(text, end="")
# 关闭文件
file.close()
4.2 readlines 一行行读取全部文件

就像read没有参数时一样,readlines可以按照的方式把整个文件中的内容进行一次性的读取,并且返回的是一个列表,其中每一行的数据为一个元素

f = open("test.txt","r")
text = f.readlines() # 一次性读取全部文件返回一个列表,每行一个字符串
print(text) 
#['hello world,I am here!\n', 'hello world,I am here!\n', 'hello world,I am here!\n', 'hello world,I am here!\n',

i = 1
for temp in text:
    print("%d:%s"%(i,temp))
    i += 1
f.close()

(五)文件读写函数综合应用

文件读写案例 --复制文件
目标
用代码的方式,来实现文件复制过程
在这里插入图片描述

5.1 小文件复制

打开一个已有文件,读取完整内容,并写入到另外一个文件

# 打开文件
file_read = open("4.py","r")
file_write = open("5.py","w")
# 读写文件
text = file_read.read()
file_write.write(text)
# 关闭文件
file_read.close()
file_write.close()
5.2大文件复制

打开一个已有文件,逐行读取的容,并顺序写入到另外一个文件

# 打开文件
file_read = open("4.py","r")
file_write = open("5.py","w")
# 读写文件
while True:
    text = file_read.readline()
    if not text:
        break
    file_write.write(text)
# 关闭文件
file_read.close()
file_write.close()
with open 管理器

解决经常会忘记关闭文件句柄,造成资源浪费,所以处理文件是往往使用 with 语句进行上下文管理。使用with语句可以创建一个上下文管理器,并在代码块执行完毕后自动关闭文件,无需手动调用close()方法。

with open(文件名, 模式) as 文件对象:
    文件对象.方法()

with open('test.txt', 'r',encoding="utf-8") as f:
    print(f.read())

# 一般写法
f = open('test.txt','r',encoding="utf-8")
f.read()
路径问题

绝对路径:它指定了文件在电脑中的具体位置,以 windows 电脑为例:

c:\user\liyue\python.py

相对路径:一般是指相对当前脚本的路径,
相对路径的写法:

# 同级目录可以直接读取
 test.txt
# 在上级目录的话需要../返回上一层目录读取
../test.txt

with open(file=r"a.txt",mode="r",encoding="utf-8") as fb:
with open(file=r"../a.txt",mode="r",encoding="utf-8") as fb:
with open(file=r"c:\user\liyue\a.txt",mode="r",encoding="utf-8") as fb:
seek 方法:通过文件对象的 seek 方法可以移动文件句柄
seek 方法接收两个参数:
 
offset 表示偏移指针的字节数
whence 表示偏移参考,默认为 0
0 表示偏移参考文件的开头,offset 必须是 >=0 的整数
1 表示偏移参考当前位置,offset 可以是负数
2 表示偏移参考文件的结尾,offset 一般是负数
with open('test.txt', 'r', encoding='utf-8') as f:
    print(f.read(3))
    # 跳转到文件开头
    f.seek(0)
    # 再读取第一个字
    print(f.read(1))
 
#响应:
爱死你
爱
文件的编码处理
    在处理文本文件时,需要考虑文件的编码格式。Python提供了多种编码处理方式,常见的有:

ascii:ASCII编码,适用于英文文本。
utf-8:UTF-8编码,适用于多种语言的文本。
latin-1:Latin-1编码,适用于西欧语言的文本。
在打开文件时,你可以指定文件的编码格式。

with open('file.txt', 'r', encoding='utf-8') as file:
    # 处理文件内容

(六)文件/目录的常用管理操作

终端/文件浏览器中可以执行常规的 文件/目录 管理操作,例如:创建、重命名、删除、改变路径、查看目录内容
在 Python 中,如果希望通过程序实现上述功能,需要导入os模块.

6.1 文件操作

在这里插入图片描述

import os
os.rename("python.txt","python3.txt")

import os 
os.remove(“python.txt”)

6.2 目录操作

在这里插入图片描述
提示:文件或者目录操作都支持 相对路径 和绝对路径

import os
os.mkdir(“张三”)

import os
os.getcwd()

import os
os.chdir("../")

在这里插入图片描述

6.3 文本文件的编码格式(科普)

文本文件存储的内容是基于字符编码的文件,常见的编码有 ASCII 编码,UNICODE 编码等

  • Python 2.x默认使用 ASCII 编码
  • Python 3.x默认使用 UTF-8 编码

ASCII 编码 和 UNICODE 编码

  • ASCII 编码 计算机中只有256个ASCII字符
  • 一个 ASCII 在内存中占用1个字节 的空间 。
  • 8个0/1的排列组合方式一共有256种,也就是2**8
    在这里插入图片描述

UTF-8 编码格式

  • 计算机中使用 1~6 个字节 来表示一个 UTF-8 字符,涵盖了地球上几乎所有地区的文字
  • 大多数汉字会使用3个字节 表示
  • UTF-8是UNICQDE编码的一种编码格式
6.4 Ptyhon 2.x 中如何使用中文

Python 2.x默认使用 ASCII 编码格式
Python 3.x默认使用 UTF-8 编码格式
在 Python 2.x文件的 第一行 增加以下代码,解释器会以 utf-8 编码来处理 python 文件

# *-* coding:utf8 *—*

这方式是官方推荐使用的!
也可以使用

# coding=utf8

unicode 字符串
在 Python 2.x中,即使指定了文件使用 UTF-8 的编码格式,但是在遍历字符串时,仍然会 以字节为单位遍历 字符串
要能够 正确的遍历字符串,在定义字符串时,需要 在字符串的引号前,增加一个小写字母 u,告诉解释器这是一个 unicode 字符串(使用 UTF-8 编码格式的字符串)

# *_*coding:utf8
#引号前面的u告诉解释器这是一个utf8编码格式的字符串
hello str = u"hello世界"
print(hello str)
for c in hello_str:
	print(c)
6.5 eval 函数

eval()函数十分强大 --将字符串 当成 有效的表达式 来求值 并 返回计算结果

# 基本的数学计算
In [1]: eval("1 + 1")
0ut[1]:2

# 字符串重复
In [2]:eval("'*'* 10")
0ut [2]:"**********"

# 将字符串转换成列表
In[3]:type(eval("[1,2,3,4,5]"))
0ut[3]: list

#将字符串转换成字典
In[4]:type(eval("{'name':'xiaoming','age': 18}"))
0ut[4]: dict

案例-计算器
需求
1.提示用户输入一个 加减乘除混合运算
2.返回计算结果

input_str = input("请输入算术题:")
print(eval(input_str))

不要滥用 eval
在开发时千万不要使用 eval直接转换 input的结果

import ('os').system('ls')

等价代码

import os
0s.system("终端命令")

执行成功,返回 0
执行失败,返回错误信息

请输入算术题:import ('os').system('rm aaa')

第二十八章:python模块的操作

(一)模块的概念

模块是 Python 程序架构的一个核心概念
每一个以扩展名 py结尾的Python 源代码文件都是一个 模块
模块名 同样也是一个 标识符,需要符合标识符的命名规则
在模块中定义的 全局变量、函数、类 都是提供给外界直接使用的 工具
模块 就好比是 工具包,要想使用这个工具包中的工具,就需要先 导入 这个模块

(二)模块的导入

在 Python 中用 import 或者 from…import 来导入相应的模块:

整个模块 (somemodule) 导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *

语法格式:

import random  # 引入随机数
x = random.randint(0, 2)  # 随机生成 0、1、2 中的一个数字,赋值给变量 x
print(x)

不推荐的导入方式

import 模块1,模块2

提示:在导入模块时,每个导入应该独占一行

import 模块1  # 推荐
import 模块2

(三)函数的调用

从某个模块导入某个函数后,调用该函数的语法格式为:模块名称.函数名称(变量)

比如,Python 中的 randint 用来生成指定范围内的随机整数,在使用 randint 之前,需要调用 random 库。该函数的语法格式为 random.randint(x, y),参数 x 和 y 代表生成随机数的区间范围,生成的随机数包括 x 和 y。

通过 模块名. 使用模块提供的工具 --- 全局变量、函数、类
random.randint(x, y)

调用实例

hm_01_测试模块1

# 全局变量
title = "模块1"
# 函数
def say_hello():
    print("我是 %s" % title)
# 类
class Dog(object):
    pass

hm_02_测试模块2

# 全局变量
title = "模块2"
# 函数
def say_hello():
    print("我是 %s" % title)
# 类
class Dog(object):
    pass

import导入模块

import hm_01_测试模块1    #导入模块 
import hm_02_测试模块2

hm_01_测试模块1.say_hello()   # 模块名称.函数名称(变量)
hm_02_测试模块2.say_hello()
dog = hm_01_测试模块1.Dog()
print(dog)
cat = hm_02_测试模块2.Cat()
print(cat)

(四)模块的别名

使用 as 指定模块的别名
如果模块的名字太长,可以使用 as 指定模块的名称,以方便在代码中的使用

import 模块名1 as 模块别名

注意:模块别名 应该符合 大驼峰命名法

import hm_01_测试模块1 as DogModule   #导入模块 使用别名
import hm_02_测试模块2 as CatModule

DogModule.say_hello()   # 别名.函数名称(变量)
CatModule.say_hello()
dog = DogModule.Dog()
print(dog)
cat = CatModule.Cat()
print(cat)

(五)form…import导入模块

如果希望 从某一个模块 中,导入部分 工具,就可以使用 from…import 的方式
import 模块名 是 一次性 把模块中 所有工具全部导入,并且通过 模块名/别名 访问

#从 模块 导入 某一个工具
from 模块名1 import 工具名

有什么好处?
导入之后
。不需要 通过 模块名.访问
。可以直接使用 模块提供的工具 - - - 全局变量、函数、类

注意:
**如果两个模块,存在同名的函数,那么后导入模块的函数,会覆盖掉先导入的函数**

from hm_01_测试模块1 import Dog   #导入模块的函数或者类
from hm_02_测试模块2 import say_hello

say_hello()   # 直接使用其他模块的函数

dog = .Dog() # 直接使用其他模块的对象
print(dog)

注意事项
开发时 import代码应该统一写在 代码的顶部,更容易及时发现冲突
一旦发现冲突,可以使用 as 关键字 给其中一个工具起一个别名

from hm_01_测试模块1 import say_hello as model2_say_hello   # 给其中一个工具起一个别名
from hm_02_测试模块2 import say_hello   # 后导入模块的函数,会覆盖掉先导入的函数
say_hello()
model2_say_hello()

(六)from…import*(知道)

从 模块 导入 所有工具

from 模块名1 import *

注意
这种方式不推荐使用,因为函数重名并没有任何的提示,出现问题不好排查

(七)模块(包)的下载

在 Python 中,模块(包)是一组函数、类、变量或语句的集合,可以被其他程序引用。Python 拥有丰富的模块库,但是在使用时有时需要下载其他的模块。

3.1 使用 pip 下载模块(包)

pip 是 Python 的包管理工具,可以用于安装、升级和卸载 Python 包。使用 pip 下载模块非常简单:右键开始菜单栏、选择“运行”、输入“cmd”并点击“确定”、在命令提示行中输入以下命令并回车:

pip install name

或者

pip install name==版本号
pip install pandas==1.0.3
3.2 使用 PyCharm 下载模块(包)
  • 打开 PyCharm,进入项目界面;
  • 点击菜单栏上的 File -> Settings;
  • 在弹出的窗中,选择 Project ->Project Interpreter;
  • 接下来点击上面界面左上角的“+”;
    然后在搜索框中搜索需要安装的第三方库,然后点击界面左下角的“Install Package”进行安装即可。
    在这里插入图片描述
3.3 在 PyCharm 代码编辑区下载模块(包)

点击底部标红的需要下载的模块名称,在悬浮的框中继续点击“Install package 包名”,即可进行模块的安装。
在这里插入图片描述

(八)模块的搜索顺序[扩展]

Python 的解释器在 导入模块 时,会:

  1. 搜索 当前目录 指定模块名的文件,如果有就直接导入
  2. 如果没有,再搜索 系统目录

在开发时,给文件起名不要和系统的模块文件重名
Python 中每一个模块都有一个内置属性__file__可以 查看模块 的 完整路径
示例

import random
#生成一个 0~10 的数字
rand = random.randint(0,10)
print(rand)

注意:如果当前目录下,存在一个random.py 的文件,程序就无法正常执行了! 这个时候, Python 的解释器会加载当前目录下的random.py 而不会加载系统的random模块

import random
print(random.__file__)

D:\python312\Lib\random.py

(九)原则 – 每一个文件都可以被导入

  • 一个 独立的 Python 文件 就是一个 模块
  • 在导入文件时,文件中 所有没有任何缩进的代码 都会被执行一遍!

实际开发场景:
在实际开发中,每一个模块都是独立开发的,大多都有专人负责,开发人员 通常会在 模块下方 增加一些测试代码,仅在模块内使用,而被导入到其他文件中不需要执行

9.1 __name_属性

name 属性可以做到测试模块的代码 只在测试情况下被运行,而在 被导入时不会被执行

__name__是Python 的一个内置属性,记录着一个字符串

  • 如果 是被其他文件导入的,__name__就是 模块名
  • 如果 是当前执行的程序 __name__是 main

hm_09_name__模块

# 全局变量、函数、类,注意:直接执行的代码不是向外界提供的工具!
def say_hello:
	print("你好,你好我是say_hello")
# 文件被导入时,能够直接执行的代码不需要被执行!
print("小明开发的这个模块")
say_hello()

hm_09_name__测试导入

import hm_09_name__模块
print("*" * 50)
小明开发的这个模块
你好,你好我是say_hello
**************************************************

上面测试代码没有调用就输出出来了,所以这些不需要调用就执行的内容是不希望被输出的,print(name)如果是当前程序执行的 name__就是__main,被其他文件导入的,__name__就是 模块名

# 全局变量、函数、类,注意:直接执行的代码不是向外界提供的工具!
def say_hello():
	print("你好,你好我是say_hello")
# 文件被导入时,能够直接执行的代码不需要被执行!
if __name__ == '__main__':
	# 文件被导入时,能够直接执行的代码不需要被执行!
	print("小明开发的这个模块")
	say_hello()

在这里插入图片描述

(十)python的包

概念

  • ·包 是一个 包含多个模块 的 特殊目录
  • 目录下有一个 特殊的文件__init__.py
  • 包名的 命名方式 和变量名一致,小写字母 +.

好处

  • 使用 import 包名 可以一次性导入 包 中所有的模块

案例演练

  1. 新建一个 hm_message 的包

  2. 在目录下,新建两个文件 sendmessage和receive_message

  3. 在 send_message 文件中定义一个 send 函数

  4. 在 receive_message 文件中定义一个 receive 函数

  5. 在外部直接导入 hm_message 的包

    __init__·py
    要在外界使用包中的模块,需要在__init__.py 中指定对外界提供的模块列表
    
# 从 当前目录 导入 模块列表
from .import send message
from .import receive message

如果我们在开发中希望把多个模块打包,就可以使用这种方式

1.新建一个 hm_message 的包
在这里插入图片描述
在这里插入图片描述
或者
在这里插入图片描述
在这里插入图片描述
2.在目录下,新建两个文件 send_message和receive_message
在这里插入图片描述
3. 在 send_message 文件中定义一个 send 函数

def send(name):
    print("发送给 %s" % name)

4.在 receive_message 文件中定义一个 receive 函数

def receive():
    return "这是来自100xxx的短信"

5.在外部直接导入 hm_message 的包

import hm_message

6.需要在__init__.py 文件中指定对外界提供的模块列表

from . import send_message
from . import receive_message

7.主程序才能使用send_message和receive_message

import hm_message

hm_message.send_message.send("liyeu")
rec = hm_message.receive_message.receive()
print(rec)

(十一)发布模块(知道)

如果希望自己开发的模块,分享 给其他人,可以按照以下步骤操作

10.1 制作发布压缩包步骤
  1. 创建 setup.py
from distutils.core import setup

setup(name="hm message",#包名
      version="1.0", # 版本
      description="itheima's 发送和接收消息模块", # 描述信息
      long_description = "完整的发送和接收消息模块", # 完整描述信息
      author="itheima",#作者
      author_email="itheima@itheima.com", #作者邮箱
      url="www.itheima.com",#主页
      py_modules=(["hm_message.send_message",
                    "hm_message.receive_message"])

有关字典参数的详细信息,可以参阅官方网站:

https://docs.python.org/2/distutils/apiref.html
  1. 构建模块
$python3 setup.py build

在这里插入图片描述
在这里插入图片描述

  1. 生成发布压缩包
$python3 setup.py sdist

在这里插入图片描述

在这里插入图片描述

10.2 安装模块

把上面制作的压缩包分享给别人以后怎么使用这个压缩包

$ tarf-zxvf hm message-1.0.tar.gz
$sudo python3 setup.py install

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

卸载模块
直接从安装目录下,把安装模块的 目录 删除就可以

$ cd /usr/local/lib/python3.5/dist-packages/
$sudo rmr hm message*

在这里插入图片描述

第二十九章:抛出异常

目标

  • 异常的概念
  • 捕获异常
  • 异常的传递
  • 自定义异常

(一)异常的概念

程序在运行时,如果 Python 解释器 遇到 到一个错误会停止程序的执行,并且提示一些错误信息,这就是异常
程序停止执行并且提示错误信息 这个动作,我们通常称之为: 抛出(raise)异常

在这里插入图片描述
程序开发时,很难将 所有的特殊情况 都处理的面面俱到,通过 异常捕获 可以针对突发事件做集中的处理,从而保证程序的 稳定性和健壮性
在这里插入图片描述

(二)捕获异常

简单的捕获异常语法
在程序开发中,如果 对某些代码的执行不能确定是否正确,可以增加 try(尝试)来 捕获异常

捕获异常最简单的语法格式:

try:
	尝试执行的代码
except:
	出现错误的处理

try 尝试,下方编写要尝试代码,不确定是否能够正常执行的代码
except 如果不是,下方编写尝试失败的代码
不管到底有没有错,程序在执行完捕获的代码后还会接着向下执行

简单异常捕获演练 --要求用户输入整数

try:
	#提示用户输入一个数字
	# 不能确定正确执行的代码
	num = int(input("请输入数字:"))
except:
	# 错误的处理代码
	print("请输入正确的数字")

(三)错误类型捕获

在程序执行时,可能会遇到 不同类型的异常,并且需要 针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
语法如下:

try:
	# 尝试执行的代码
	pass
except 错误类型1:
	# 针对错误类型1,对应的代码处理
	pass
except(错误类型2,错误类型3):
	# 针对错误类型2 和 3,对应的代码处理
	pass
except Exception as result:
	print("未知错误 %s"% result)

当Python 解释器 抛出异常 时,最后一行错误信息的第一个单词,就是错误类型
在这里插入图片描述

异常类型捕获演练–要求用户输入整数
需求
1.提示用户输入一个整数
2.使用 8除以用户输入的整数并且输出

try:
    # 提示用户输入一个整数
    num = int(input("输入一个整数:"))
    # 使用 8 除以用户输入的整数并且输出
    result =8 / num
    print(result)
except ZeroDivisionError:
    print("除θ错误")
except ValueError:
    print("请输入正确的整数")

(四)捕获未知错误

在开发时 要预判到所有可能出现的错误,还是有一定难度的,如果希望程序 无论出现任何错误,都不会因为Python 解释器 抛出异常而被终止,可以再增加一个except
语法如下:

except Exception as result:
	print("未知错误 %s"% result)
try:
    # 提示用户输入一个整数
    num = int(input("输入一个整数:"))

    # 使用 8 除以用户输入的整数并且输出
    result =8 / num
    print(result)
except ZeroDivisionError:
    print("除0错误")
except ValueError:
    print("请输入正确的整数")
except Exception as result:
    print("未知错误 %s" % result)

(五)异常捕获完整语法

在实际开发中,为了能够处理复杂的异常情况,完整的异常语法如下:
提示:
有关完整语法的应用场景,在后续学习中,结合实际的案例会更好理解
现在先对这个语法结构有个印象即可

try:
	# 尝试执行的代码
	pass
except 错误类型1:
	# 针对错误类型1,对应的代码处理
	pass
except 错误类型2:
	#针对错误类型2,对店的代码处理
	pass
except(错误类型3,错误类型4):
	# 针对错误类型3 和 4,对应的代码处理
	pass
except Exception as result:
	# 打印错误信息
	print(result)
else:
	# 没有异常才会执行的代码
	pass
finally:
	# 无论是否有异常,都会执行的代码
	print("无论是否有异常,都会执行的代码")
  • else 只有在没有异常时才会执行的代码
  • finally 无论是否有异常,都会执行的代码

之前一个演练的 完整捕获异常 的代码如下:

try:
    # 提示用户输入一个整数
    num = int(input("输入一个整数:"))

    # 使用 8 除以用户输入的整数并且输出
    result =8 / num
    print(result)
except ZeroDivisionError:
    print("除0错误")
except ValueError:
    print("请输入正确的整数")
except Exception as result:
    print("未知错误 %s" % result)
else:
	print("尝试成功")
finally:
	print("无论是否有异常,都会执行的代码")

print("*" * 50)

没有错误的时候执行效果

输入一个整数:1
8.0
尝试成功
无论是否有异常,都会执行的代码
**************************************************

出现错误的执行效果

输入一个整数:00错误
无论是否有异常,都会执行的代码
**************************************************

(五)异常的传递

异常的传递 --当 函数/方法执行出现异常,会将异常传递 给 函数/方法 的调用一方,如果传递到主程序,仍然没有异常处理,程序才会被终止

提示

  • 在开发中,可以在主函数中增加 异常捕获
  • 而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的 异常捕获 中
  • 这样就不需要在代码中,增加大量的 异常捕获,能够保证代码的整洁

需求

  1. 定义函数 emo1()提示用户输入一个整数并且返回
  2. 定义函数 demo2()调用 demo1()
  3. 在主程序中调用 demo2()
1 def demo1():
2    return int(input("请输入一个整数:"))
3 def demo2():
4    return demo1()
5
6 print(demo2())

将异常传递给函数/方法的调用一方 从第2行开始传递到4,6行
在这里插入图片描述
在主函数中增加异常捕获以后 主函数中调用的demo2()函数,出现异常,都会传递到主函数的异常捕获中,不需要在上面增加异常捕获了

def demo1():
    return int(input("请输入一个整数:"))
def demo2():
    return demo1()
    
# 利用异常的传递性 在主程序捕获异常
try:
    print(demo2())
except ValueError:
    print("请输入正确的整数")
except Exception as result:
    print("未知错误 %s" % result)

(六)抛出 raise 异常

应用场景
在开发中,除了代码执行出错 ,Python 解释器会抛出异常之外,还可以根据应用程序特有的业务需求主动抛出异常。
示例
提示用户输入密码,如果 长度少于 8,抛出 异常
在这里插入图片描述
注意
当前函数 只负责 提示用户输入密码,如果 密码长度不正确,需要其他的函数进行额外处理,因此可以 抛出异常,由其他需要处理的函数 捕获异常

抛出异常

Python 中提供了一个Exception 异常类,在开发时,如果满足 特定业务需求时,希望 抛出异常,可以:

  1. 创建一个 Exception 的对象
  2. 使用 raise 关键字 抛出 异常对象

需求

  • 定义 input_password 函数,提示用户输入密码
  • 如果用户输入长度<8,抛出异常
  • 如果用户输入长度 >=8,返回输入的密码
def input_password():
    password = input("Enter your password: ")

    if len(password) >= 8:
        return password
    print("主动抛出异常")
    # 3.如果 <8 主动抛出异常
    # 1> 创建异常对象
    ex = Exception("密码长度不够")
    # 2>主动抛出异常
    raise ex
try:
    print(input_password())
except Exception as ex:
    print(ex)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HACKNOE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值