python入门(10)异常、模块、包
一、异常
1.异常的概念
- 异常:程序在运行时,如果python解释器遇到一个错误,会停止程序的执行,并且提示一些错误信息。
- 程序停止执行并且提示错误信息这个动作,我们通常称之为:抛出异常。
- 程序开发时,很难将所有的特殊情况都处理的绵绵俱到,通过异常捕获可以针对突发事件做集中的处理,从而保证程序的稳定性和健壮性。
2.捕获异常
- 简单的捕获异常语法
在程序开发中,如果对某些代码的执行不能确定是否正确,可以增加try(尝试)来捕获异常
捕获异常最简单的语法格式:
try:
尝试执行的代码
except:
出现的错误
try 尝试,下方编写要尝试代码,不确定是否能够正常执行的代码
except 如果不是,下方编写尝试失败的代码
try:
# 不能确定正确执行的代码
num = int(input("请输入一个整数:"))
except:
# 错误的处理代码
print("请输入正确的整数")
print("-" *50)
- 错误类型捕获
在程序执行时,可能会遇到不同类型的异常,并且需要针对不同类型的异常,做出不同的响应,这时,就需要捕获错误类型
语法如下
try:
# 尝试执行的代码
except 错误类型1:
# 针对错误类型1,对应的代码处理
pass
except (错误类型2,错误类型3):
# 针对错误类型2和3,对应的代码处理
pass
except Exception as result:
print("未知错误 %s" % result)
当python解释器抛出异常时,最后一行错误信息的第一个单词,就是错误类型
需求:提示用户输入一个整数,使用8除以用户输入的整数并且输出
案例:
try:
# 提示用户输入一个整数
num = int(input("请输入一个整数:"))
# 使用8除以用户输入的整数并且输出
result = 8 / num
print(result)
except ZeroDivisionError:
# 错误的处理代码
print("除0错误")
except ValueError:
# 错误的处理代码
print("请输入正确的整数")
- 捕获未知错误
在开发时,要预判到所有可能出现的错误,还是有一定难度的,如果希望程序无论出现任何错误,都不会因为python解释器抛出异常而被终止,可以再增加一个except
# 捕获未知错误
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:
# 没有异常才会执行的代码
finally:
# 无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")
else 只有在没有异常时才会执行的代码
finally 无论是否有异常,都会执行的代码
案例:
try:
# 提示用户输入一个整数
num = int(input("请输入一个整数:"))
# 使用8除以用户输入的整数并且输出
result = 8 / num
print(result)
except ZeroDivisionError:
# 错误的处理代码
print("除0错误")
# 捕获未知错误
except Exception as result:
print("未知错误 %s " %result)
else:
print("尝试成功")
finally:
print("无论是否出现错误都会执行的代码")
3.异常的传递
- 异常的传递 – 当函数/方法执行出现异常,会将异常传递给函数/方法的调用一方
- 如果传递到主程序,仍然没有异常处理,程序才会被终止,提示:在开发中,可以在主函数中增加异常捕获,而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获中,这样就不需要在代码中,增加大量的异常捕获,能够保证代码的整洁
- 异常传递案例
def demo1():
return int(input("请输入一个整数:"))
def demo2():
return demo1()
# 利用异常的传递性,在主程序中捕获异常
try:
print(demo2())
except Exception as result:
print("未知错误 %s " %result)
4.抛出raise异常–自定义异常
- 应用场景
在开发中,除了代码执行出错python解释器会抛出异常之外,还可以根据应用程序特有的业务需求主动抛出异常 - 示例:提示用户输入密码,如果长度少于8,抛出异常
当前函数只负责提示用户输入密码,如果密码长度不正确,需要其他的函数进行额外处理,因此可以抛出异常,由其他需要处理的函数捕获异常。 - 抛出异常
python中提供了一个Exception 异常类
在开发时,如果满足特定业务需求时 ,希望抛出异常,可以:创建一个Exception的对象,使用raise关键字抛出异常对象 。
需求:定义input_password函数,提示用户输入密码,如果用户输入长度 < 8,抛出异常,如果用户输入长度 >= 8,返回输入的密码
代码:
def input_password():
# 1.提示用户输入密码
pwd = input("请输入一个整数:")
# 2.判断密码长度 》=8,返回用户输入的密码
if len(pwd) >= 8:
return pwd
# 3.如果 <8 主动抛出异常
print("主动抛出异常")
# 3.1 创建异常对象 --- 可以使用错误信息字符串作为参数
ex = Exception("密码长度不够")
# 3.2 主动抛出异常
raise ex
# 提示用户输入密码
try:
print(input_password())
except Exception as result:
print("未知错误 %s " %result)
二、模块
1.模块的概念
- 每一个以扩展名py结尾的python源代码都是一个模块
- 模块名同样也是一个标识符,需要符合标识符的命名规则
- 在模块中定义的全局变量、函数、类都是提供给外界直接实用的工具
- 模块就好比工具包,要想使用这个工具包中的工具,就需要先导入这个模块
2.模块的两种导入方式
- import导入
import 模块1
import 模块2
提示:在导入模块时,每个导入应该独占一行
导入之后,通过模块名.
使用模块提供的工具 ---- 全局变量、函数、类
- 案例
三个文件
testmodule1.py、testmodule2.py、main.py
testmodule1.py代码
# 全局变量
title = "模块1"
# 函数
def say_hello():
print("我是 %s " % title)
# 类
class Dog(object):
pass
testmodule2.py代码
# 全局变量
title = "模块2"
# 函数
def say_hello():
print("我是 %s " % title)
# 类
class Cat(object):
pass
main.py代码
import testmodule_1
import testmodule_2
testmodule_1.say_hello()
testmodule_2.say_hello()
dog = testmodule_1.Dog()
print(dog)
cat = testmodule_2.Cat()
print(cat)
运行截图:
3. 使用as指定模块的别名
如果模块的名字太长,可以使用as指定模块的名称,以方便在代码中使用
import 模块名 as 模块别名
注意:模块别名 应该符合大驼峰命名法
import testmodule_1 as DogModule
import testmodule_2 as CatModule
DogModule.say_hello()
CatModule.say_hello()
dog = DogModule.Dog()
print(dog)
cat = CatModule.Cat()
print(cat)
4.from…import导入
如果希望从某一个模块中,导入部分工具,就可以使用from...import
的方式
import 模块名
是一次性把模块中所有工具全部导入,并且通过模块名/别名 访问
# 从模块中导入某一个工具
from 模块名1 import 工具名
导入之后,不需要通过 模块名.
,可以直接使用模块提供的工具-----全局变量、函数、类
from testmodule_1 import Dog
from testmodule_2 import say_hello
say_hello()
dog = Dog()
print(dog)
注意:如果两个模块,存在同名的函数,那么后导入模块的函数,会覆盖掉先导入的函数
开发时import 代码应该统一写在代码的顶部,更容易及时发现冲突,一旦发现冲突,可以使用as
关键字给其中一个工具起一个别名
from testmodule_1 import say_hello as module1_say_hello
from testmodule_2 import say_hello
module1_say_hello()
say_hello()
5. from…import 导入所有工具
# 从 模块 导入 所有工具
from 模块1 import *
注意:这种方式不推荐使用,因为函数重名并没有任何的提示,出现问题不好排查
- 模块的搜索顺序
python的解释器在导入模块时,会搜索当前目录指定模块名的文件,如果有就直接导入,如果没有,再搜索系统目录。
在开发时,给文件起名,不要和系统的模块文件重名
python中每一个模块都有一个内置属性__file__
可以查看模块的完整路径
示例:
import random
# 查看模块的完整路径
print(__file__)
rand = random.randint(0,10)
print(rand)
注意:如果当前目录下,存在一个random.py的文件,程序就无法正常执行了,这个时候,python的解释器会加载当前目录下的random.py而不会加载系统的random模块。
6. 原则—每一个文件都应该是可以被导入的
一个独立的python文件就是一个模块
在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍
全局变量、函数、类是模块向外界提供的工具,直接执行的代码不是向外界提供的工具
- 实际开发场景
在实际开发中,每一个模块都是独立开发的,大多都有专人负责,开发人员通常会在模块下方增加一些测试代码,测试代码仅在模块内使用,而被导入到其他文件中不需要执行 __name__
属性
__name__
属性可以做到,测试模块的代码只在测试情况下被运行,而在被导入时不会被执行。
__name__
是python的一个内置属性,记录着一个字符串
如果是被其他文件导入的,__name__
就是模块名,如果是当前执行的程序,__name__
是__main__
# 全局变量
title = "模块1"
# 函数
def say_hello():
print("我是 %s " % title)
if __name__ == "__main__":
print("模块测试代码")
三、包
1.包的概念
包是一个包含多个模块的特殊目录。目录下有一个特殊的文件__init__.py
,包的命名方式和变量名一致,小写字母+_
。
2.使用包的优势
使用 import 包名
可以一次性导入包中所有的模块
3.__init__
.py
要在外界使用包中的模块,需要在__init__.py中指定对外界提供的模块列表
# 从 当前目录 导入 模块列表
from . import send_message
from . import receive_message
4.案例演示
新建一个hm_message的包
在目录下,新建两个文件send_message和receive_message
在send_message文件中定义一个send函数
在receive_message文件中定义一个receive函数
在外部直接导入hm_message的包
文件结构树:
新建包的方法:选中项目名–>右键新建–>python软件包(python package)
其中:新建的包中会自动包含一个__init__
.py文件
send_message代码:
def send(text):
print("正在发送 %s ...." % text)
receive_message代码:
def receive():
return "这是来自100xx的短信"
__init__
.py文件代码:
from . import send_message
from . import receive_message
main文件代码:
import hm_message
hm_message.send_message.send("hello")
txt = hm_message.receive_message.receive()
print(txt)
运行截图:
四、模块的制作
如果希望自己开发的模块,分享给其他人,可以按照以下步骤操作
1.制作发布压缩包步骤
- 创建setup.py的文件
- 构建模块
$ python3 setup.py build - 生成发布压缩包
$ python3 setup.py sdist
2.window系统下制作模块压缩包
- 包同级目录下新建setup.py文件,setup.py文件中输入以下内容,具体可根据自己信息更换。
from distutils.core import setup
setup(name="hm_message",#包名
version="1.0",#版本
description="接收消息和发送消息",#描述信息
long_description="完整的发送和接收消息模块",#完整描述信息
author="dts",#作者
author_email="123456789@qq.com",#作者邮箱
url="www.baidu.com",#主页
py_modules=["hm_message.send_message",
"hm_message.receive_message"])
文件目录结构树
-
win+r快捷键打开运行窗口,运行窗口输入cmd进入命令行
-
将命令行路径切换到setup.py文件所在目录,setup文件所在目录----D:\softwarework\pycharm\test02
切换盘符 ,由c盘 —> d盘
切换具体路径
-
使用
setup.py build
命令生成模块
-
使用
setup.py sdist
命令生成发布压缩包
-
可以通过setup.py文件同目录下看到一个dist文件夹,dist文件夹下就有压缩包
3、安装模块
linux系统下两步骤:通过命令行操作
$ tar -zxvf hm_message-1.0.tar.gz
$ sudo python3 setup.py install
window系统下实际演示安装模块
- 找到需安装的.gz模块压缩包
- 通过命令行解压,安装,首先命令行路径切换到与压缩包同一目录下,如果不会命令行切换路径,可以参考上文制作模块压缩包时如何切换路径。
- 解压模块压缩包
- 切换命令行路径至解压模块文件夹中
- 安装模块
- 可以在项目中导入模块使用了
4.卸载模块
直接从安装目录下,把安装模块的目录删除就可以
- window系统下卸载模块
找到模块安装路径,可以通过模块名.__file__
知道模块安装路径,也可以自行百度模块默认安装路径
找到模块安装文件夹,直接删除就可以卸载模块
5.pip安装第三方模块
第三方模块通常是指由知名的第三方团队开发的并且被程序员广泛使用的python包\模块
例如:pygame就是一套非常成熟的游戏开发模块
pip是一个现代的,通用的python包管理工具,提供了对python包的查找、下载、安装、卸载等功能
安装和卸载命令如下:
pip install 模块名
pip uninstall 模块名
pip install pygame
pip uninstall pygame