异常、模块、包

异常处理

什么是异常

异常就是 非正常 没有达到预期目标 的非语法错误,会影响程序正常执行,Python 解释器不能正常处理的问题

  • 异常分两种:
    • 语法错误导致的异常
    • 逻辑错误导致的异常
  • 对于不可预知的异常错误,可以使用 try…except…对异常进行处理

常用的异常类继承关系

1
2
3
4
try:
可能发生异常错误的代码
except:
如果发生了异常则进入except代码块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 异常例子
varlist = [1,2,3]
print(varlist[3])

"""
运行结果为:
Traceback (most recent call last):
File "/Users/zachary/PycharmProjects/Python教程阶段1/code_oop/41什么是异常.py", line 6, in <module>
print(varlist[3])
IndexError: list index out of range

其中:
IndexError 异常类
list index out of range 异常信息
"""

# 异常处理除法
val = input("请输入一个数字:")
try:
num = int(val)
res = 10 / num
print(res)
except ValueError as e:
print("not input number value")
except ZeroDivisionError as e:
print("can not input 0")




# 异常处理文件
try:
with open('./user.txt', 'r') as file:
res = file.read()
print(res)
except:
print('file not exist')

print('other program')
# file not exist
# other program

try_except_else_finally

  • try 执行可能会引发错误的代码块
  • except 捕获异常并输出
  • else 如果 try 代码块没有出错就会执行
  • finally 无论 try 有无错误都会执行
  • raise 可以抛出一个异常
  • assert 断言,后面的表达式如果正确 什么也不做,如果表达式错误,则抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 1.处理指定的异常,引发了非指定的异常,无法处理
try:
varlist = [1, 2, 3]
print(varlist[3])
except IndexError as e:
print(e) # list index out of range

# 2.多分支处理异常
try:
s = 'duanduan'
res = int(s)
except ValueError as e:
print('ValueError', e)
except KeyError as e:
print('KeyError', e)
except IndexError as e:
print('IndexError', e)
# ValueError invalid literal for int() with base 10: 'duanduan'


# 3.通用异常类 Exception
try:
s = 'duanduan'
res = s[10]
except Exception as e:
print('Exception', e)
# Exception string index out of range


# 4.多分支异常类+通用异常类
try:
s = 'duanduan'
res = int(s)
except KeyError as e:
print('KeyError', e)
except IndexError as e:
print('IndexError', e)
except Exception as e:
print('Exception', e)
# Exception invalid literal for int() with base 10: 'duanduan'


# 5.try except else
try:
s = 'duandaun'
res = str(s)
except KeyError as e:
print('KeyError', e)
except IndexError as e:
print('IndexError', e)
except Exception as e:
print('Exception', e)
else:
print('try中没有错误')
# try中没有错误


# 6.try except else finally
try:
s = 'duandaun'
res = str(s)
except KeyError as e:
print('KeyError', e)
except IndexError as e:
print('IndexError', e)
except Exception as e:
print('Exception', e)
else:
print('try中没有错误')
finally:
print('代码执行完毕,这句肯定输出')
# try中没有错误
# 代码执行完毕,这句肯定输出


# 7. 主动抛出异常 raise
try:
raise Exception()
except Exception as e:
print('Exception', e)
# Exception


# 8. assert 断言 后面的表达式正确什么耶不做 错误的话 抛出异常
try:
assert 1 == 2
except AssertionError as e:
print('AssertionError', e)
# AssertionError

自定义异常类

1
2
3
class InvalidInputArgument(Exception):
def __init__(self,*args):
super().__init__(args)

当异常出现时,对异常信息写入日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"""
在出现异常后,对异常进行处理,并且把异常信息写入日志
日志的基本格式:
日期时间 异常的级别
异常信息:引发的异常类,异常的信息,文件及行号
"""

import traceback
import logging

class Myexception():
def __init__(self):
# logging 基本配置
logging.basicConfig(
filename='./error.log', # 日志存储的文件目录
format='%(asctime)s %(levelname)s \n %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)

# 写入日志
logging.error(traceback.format_exc())


try:
res = int('duanduan')
except:
Myexception()

模块与包

定义的一个 python 文件,后缀名为.py 这个文件被称为模块 模块中通常会定义一些相似的类,函数等代码内容,提供给别的程序引入后使用

  • 系统模块
    • 系统模块就是一个 python 的程序脚本,专门提供给我们自己的程序使用。
    • 它们是安装好 python 环境的时候,就已经存在的,需要的时候可以使用 import 导入到程序中使用
    • import logging, json, math, time
  • 自定义模块
    • 就是自己创建的一个 python 脚本,定义一些类或方法,供别的脚本导入后使用

自定义模块的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用方式之一
import Exception

try:
res = int('duanduan')
except:
Exception.MyException()
Exception.output()
print(Exception.var)

# 使用方式之二
from Exception import *

try:
res = int('duanduan')
except:
MyException()
output()
print(var)

自定义包和使用

包可以理解为是一个文件夹,里面包含了多个 python 文件

  • 包的结构
1
2
3
4
5
6
7
8
└── package_fa
├── __init__.py # 包的标志性文件(可以有内容,也可以没有)
├── a.py # a模块(文件)
├── b.py # b模块(文件)
└── package_son
├── __init__.py
├── c.py
└── d.py

实际上,**init.py 可以实现一个功能在导入包的时候,想要使用from package_fa import *的时候需要在 package_fa下的**init.py下写入:**all = [‘module1’,’module2’,…]这里的module1,2 指的就是在 package_fa下的模块名称**

来做一个测试叭,首先在当前项目文件夹下创建一个类似上述的目录结构 之后编写代码进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 使用1:导入指定的包中的模块
from package_fa import a

a.funca() # funca

# 使用2:从指定包的指定模块导入指定的内容
from package_fa.b import funcb

funcb() # funcb

# 使用3:从指定包的子包中导入模块
from package_fa.package_son import c

c.funcc() # funcc

# 使用4:从指定包的子包的指定模块导入指定内容
from package_fa.package_son.d import funcd

funcd() # funcd


# 使用5: 需要在package_fa 中的__init__.py写入模块列表
# 格式为: __init__.py ===> __all__ = ['a','b']
from package_fa import *
a.funca()

可以讲一下:name = main,

导入方式的分类

绝对导入

  • 会使用[搜索路径]去查找和导入指定的包或模块 import module import package import package.module from module import content from package import module from package.module import content

相对导入

from .package/module import module/content from ..package/module import module/content

. 表示当前目录 .. 表示上一级目录

1
2
3
4
5
6
7
8
9
10
11
12
def funcc():
print('funcc')


# 假设在c.py中需要d.py 可以使用相对导入,但是不要直接运行c.py
from .d import funcd
funcd()


# 假设想要在c中使用上一级的a
from .. import a
a.funca()
1
2
3
from package_fa.package_son import c
# funcd
# funca

单入口程序

单入口程序指的是整个程序都是经过一个主程序文件在运行,其他程序都封装成了包或模块

1
2
3
4
5
6
7
8
9
10
11
ATM
└── main.py # 当前程序的主入口文件,单入口文件,唯一直接运行的文件
├── package/ # 主要程序模块包
├── __init__.py # 包的初始化文件
├── View.py # 视图函数模块
├── Controller.py # 控制器模块
├── Card.py # 银行卡模块
└── User.py # 用户模块
└── databases/ # 数据存储文件夹
├── user.txt
└── user_id_card.txt

Python 中的第三方库的管理 pip

第三方库的管理网站https://pypi.org/

pip 的使用

  • 查看 pip 版本 pip -V
  • 安装 pip install -i <仓库镜像的地址> 包名(库名)
    • pip3 install -i [http://mirrors.aliyun.com/pypi/simple/](http://mirrors.aliyun.com/pypi/simple/) --trusted-host mirrors.aliyun.com mysqlclient==2.1.1
  • 常用镜像地址
    • 阿里云 http://mirrors.aliyun.com/pypi/simple/
    • 豆瓣 http://pypi.douban.com/simple/
    • 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
    • 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
    • 华中科技大学 http://pypi.hustunique.com/
  • 安装指定版本的包 pip install <package>==<版本>
  • 查看已经安装的 package pip list
  • 检查 package 是否已经过期 pip list outdated
  • 卸载 package pip uninstall <包名>
  • 查看 package 的依赖 pip show <包名>

Python 中的虚拟环境 venv

虚拟环境就是在当前的系统环境中,去配置另外一个 python 的运行环境,是可以创建多个不同的虚拟环境 python 的虚拟环境相互独立,互不影响

  • 虚拟环境中可以在没有权限的情况下安装库(Linux 系统中可能会出现的问题)
  • 不同的应用可以使用不同的库或者不同的版本
  • 虚拟环境中的库升级也不影响其他环境
  • 虚拟环境可以作为一个项目的专有环境,在需要部署的时候,可以一键导出项目所需要的包
  • 如何创建一个虚拟环境
    • 使用 pycharm 创建
    • 自己安装独立的虚拟环境
      • 安装虚拟环境工具 pip install virtualenv
      • 创建虚拟环境 python3 -m venv <虚拟环境名称>
      • 激活虚拟环境 source <虚拟环境名称>/bin/activate
      • 退出虚拟环境 deactivate
      • 导出当前环境项目包 pip freeze > ./requirements.txt
      • 通过 requirement 安装依赖包 pip install -r requirement.txt

更新: 2024-01-27 22:21:03
原文: https://www.yuque.com/zacharyblock/cx2om6/ql4zdyscp3ffck91