一、异常
1、了解异常
异常的组成: `异常类型`: `异常具体的描述信息
# 异常: 程序运行过程中,代码遇到错误,给出错误的提示
print('其他的代码......')
num = input('请输入一个数字:')
# ZeroDivisionError: division by zero
# ValueError: invalid literal for int() with base 10: 'a'
num = 10 / int(num)
print('计算得到的结果是:', num)
print('其他的代码......')
2. 捕获单个异常
# 异常: 程序代码在运行过程中遇到的错误, 程序会报错,会终止程序代码的运行. # 异常捕获: 是指在程序代码运行过程中,遇到错误, 不让程序代码终止,让其继续运行, 同时可以给使用者一个提示信息 # 并记录这个错误, 便于后期改进 """ try: ? ? 可能发生异常的代码 except 异常的类型: ? ? 发生异常执行的代码
print('其他的代码......')
num = input('请输入一个数字:')
# ZeroDivisionError: division by zero
# ValueError: invalid literal for int() with base 10: 'a'
try:
num = 10 / int(num)
print('计算得到的结果是:', num)
except ZeroDivisionError:
print('你输入有误,请再次输入')
print('其他的代码......')
3、捕获多个异常
try: ? ? 可能发生异常的代码 except (异常的类型1, 异常类型2, ...): ? ? 发生异常执行的代码
print('其他的代码......')
num = input('请输入一个数字:')
# # ZeroDivisionError: division by zero
# # ValueError: invalid literal for int() with base 10: 'a'
try:
a = int(num)
num = 10 / a
print('计算得到的结果是:', num)
except (ZeroDivisionError, ValueError):
print('你输入有误,请再次输入')
print('其他的代码......')
"""
try:
可能发生异常的代码
except 异常类型1:
发生异常1,执行的代码
except 异常类型2:
发生异常2,执行的代码
except ...:
pass
"""
print('其他的代码......')
num = input('请输入一个数字:')
# ZeroDivisionError: division by zero
# ValueError: invalid literal for int() with base 10: 'a'
try:
a = int(num)
num = 10 / a
print('计算得到的结果是:', num)
except ZeroDivisionError:
print('你输入有误,请再次输入')
except ValueError:
print('输入有误,请输入数字')
print('其他的代码......')
4. 打印异常信息
try: ? ? 可能发生异常的代码 except (异常的类型1, 异常类型2, ...) as 变量名: ? ? 发生异常执行的代码 ? ? print(变量名)
print('其他的代码......')
num = input('请输入一个数字:')
# ZeroDivisionError: division by zero
# ValueError: invalid literal for int() with base 10: 'a'
try:
a = int(num)
num = 10 / a
print('计算得到的结果是:', num)
except (ZeroDivisionError, ValueError) as e:
# 可以打印出异常的具体信息 习惯将变量名字写作e
print('你输入有误,请再次输入', e)
print('其他的代码......')
5、捕获所有的异常
try: ? ? 可能发生异常的代码 except: ? # 缺点, 不能获取异常的描述信息 ? ? 发生异常执行的代码 ? ?? ? ?? ============== try: ? ? 可能发生异常的代码 except Exception as e: ? ? 发生异常执行的代码 ? ? print(e) ? ? pass
# Exception 是常见异常类的父类, ZeroDivisionError --> ArithmeticError --> Exception --> BaseException ?---> object ValueError --> Exception --> BaseException ?---> object
print('其他的代码......')
num = input('请输入一个数字:')
try:
a = int(num)
num = 10 / a
print('计算得到的结果是:', num)
f = open('1.txt', 'r')
except Exception as e:
print('你输入有误,请再次输入', e)
print('其他的代码......')
6、异常的完整结构
try: ? ? 可能发生异常的代码 except Exception as e: ? ? 发生异常执行的代码 ? ? print(e) else: ? ? 代码没有发生异常,会执行 finally: ? ? 不管有没有发生异常,都会执行
print('其他的代码......')
num = input('请输入一个数字:')
try:
a = int(num)
num = 10 / a
print('计算得到的结果是:', num)
except Exception as e:
print('你输入有误,请再次输入', e)
else:
print('没有发生异常,我会会执行')
finally:
print('不管有没有发生异常,我都会执行')
print('其他的代码......')
7、异常的传递
是 python 异常处理的底层机制,是原理层面上的,不需要我们自己写代码实现,是 python 已经实现好的.
异常传递: 当一行代码发生异常之后,会向外层将这个异常进行传递,指导被捕获或者程序报错为止. 1. try 嵌套 2. 函数嵌套
print('其他的功能代码.....')
num = input('请输入数字:')
try:
try:
a = int(num) # ValueError
except ZeroDivisionError:
print('发生异常')
finally:
print('我都执行了....')
num = 10 / a
print(f'计算的结果<<{num}>>')
except Exception as e:
print(e)
print('其他的功能代码.....')
def func1():
print('-------1---------')
num = input('请输入数字') # 0
num = 10 / int(num) # 假设0 是计算的出来的
print(num)
print('-------2---------')
def func2():
print('-------3---------')
func1()
print('-------4---------')
try:
print('-------5---------')
func2()
print('-------6---------')
except Exception as e:
print('-------7---------')
print(e)
# 调用的顺序为:5 3 1 7
9、抛出自定义异常
程序代码为什么会报错? 因为不符合语法, 因为 python 的作者在代码中使用了 if 判断,如果除数为 0 ,就会在代码中抛出异常错误, 抛出异常: ? ? raise 异常对象 ?# 当程序代码遇到 raise 的时候,程序就报错了 ? ?? 异常对象 = 异常类(参数) ?
抛出自定义异常: ? ? 1. 自定义异常类,继承 Exception 或者 BaseException? ? ? 2. 选择书写,定义 __init__方法,定义__str__ 方法 ? ? 3. 在合适的时机抛出异常对象即可
# 1. 定义异常类, 密码长度不足的异常
class PasswordLengthError(Exception):
# def __str__(self):
# return 'xxxxxx'
pass
def get_password(): # 等同于系统定义函数
password = input('请输入密码:')
if len(password) >= 8:
print('密码长度合格')
else:
# 抛出异常
raise PasswordLengthError('密码长度不足8位')
# print('密码长度不足8位')
try:
get_password() # 调用系统的函数
except PasswordLengthError as e:
print(e)
print('其他代码.....')
二、模块
import random random.randint(a, b) ?产生[a,b] 之间的随机整数, 包含 b的 import os ? python 就是一个 python 代码文件,是别人已经写好的代码文件,文件中的函数类以及变量,我们都可以使用.
使用模块的好处: ?直接使用别人已经实现好的功能,
1、模块的制作
模块就是一个 python 文件 制作一个模块,其实就是定义一个 python 代码文件 注意点: 模块的名字要遵循标识符的规则(由字母,数字和下划线组成,不能以数字开头) ? ?? 模块中可以定义变量,定义函数,定义类
2、模块的导入
想要使用模块中的内容,必须先导入模块? 注意点: 如果导入的是自己书写的模块,使用的模块和代码文件需要在一个目录中
# 想要使用模块中的内容,必须先导入模块
# 方法一 import 模块名
# 使用: 模块名.功能名
import my_module1
print(my_module1.num) # 使用my_module1中的变量num
my_module1.func() # 调用my_module1中 func函数
dog = my_module1.Dog() # 调用my_module1中的类创建对象
dog.show_info()
# 方法二 from 模块名 import 功能名1, 功能名2, ....
# 使用: 功能名
# 注意点: 如果存在同名的方法名,则会被覆盖
from my_module2 import func, num
from my_module1 import num
func()
print(num)
# 方法三 from 模块名 import * # 将模块中所有的功能进行导入
# 使用: 功能名
from my_module2 import *
print(num)
func()
dog = Dog()
dog.show_info()
# as 起别名.可以对模块和功能起别名,
# 注意: 如果使用as别名,就不能再使用原来的名字
import my_module1 as mm1
from my_module1 import func as m1_func
from my_module2 import func as m2_func
mm1.func()
m1_func()
m2_func()
module1:
num = 1
def func():
print('my_module1 func .....')
class Dog(object):
@staticmethod
def show_info():
print('这是一个Dog类 , my_module1 dog类')
pass
module2:
num = 2
def func():
print('my_module2 func .....')
class Dog(object):
@staticmethod
def show_info():
print('这是一个Dog类 , my_module2 dog类')
pass
3、注意点
# 自己定义的模块名字,不要和系统中你要使用的模块名字相同
import random
import sys
# 模块的搜索顺序, 当前目录 ---> 系统目录 ---> 程序报错
print(sys.path)
a = random.randint(1, 5)
print(a)
三、包的导入
包: 功能相近或者相似的模块放在一个目录中,并在目录中定义一个 __init__.py 文件,这个目录就是包
# 方法一 import 包名.模块名
import my_package.my_module1
import my_package.my_module2 as mm2
my_package.my_module1.func()
mm2.func()
# 方法2 from 包名.模块名 import 功能名
from my_package.my_module1 import func
from my_package.my_module2 import *
func()
# 方法三 from 包名 import * # 导入的是__init__.py中的内容
from my_package import *
from 异常.my_module1 import func
func()
四、__name__和__all__方法
my_random:
import random
import sys
# 模块的搜索顺序,当前目录 ---> 系统目录 ---> 程序报错
print(sys.path)
a = random.randint(1, 5)
print(a)
my_module3:
# __all__ = ['num', 'func']
__all__ = ('num', 'func')
num = 3
def func():
print('my_module3 func .....')
class Dog(object):
@staticmethod
def show_info():
print('这是一个Dog类 , my_module3 dog类')
pass
__all__方法的调用?
"""
__all__ 变量,可以在每个代码文件中(模块中)定义, 类型是元组,列表
作用: 影响 form 模块名 import * 导入行为,另外两种导入行为不受影响
1. 如果没有定义__all__ 变量, 模块中的所有功能,都可以被导入
2. 如果定义__all__ 变量,只能导入 变量中定义的内容
"""
from 异常.my_module3 import *
from 异常.my_module3 import Dog
print(num)
func()
dog = Dog() # 会报错
dog.show_info()
__name__方法
import my_calc # 模块的导入,会执行模块中的代码
my_calc.add(100, 200)
|