目录
1. 模块(module)
1.1 模块化程序设计理念
1.1.1 API 和功能描述要点
API(Application Programming Interface 应用程序编程接口)用于描述模块中提供的函数、类的功能和使用方式。
使用时一般先导入模块,然后通过help(模块名)查看模块的API。
也可在模块的第一行增加一个文档字符串,用于描述模块的相关功能,然后通过__doc__获得文档字符串的内容。
1.1.2 模块的创建和测试代码
每个模块都有一个名称,通过特殊变量__name__可以获取模块的名称。
一般情况下,模块名字对应源文件名。
import math
math.__name__ #输出'math'
但当一个模块被作为程序入口时(主程序、交互式提示符下),它的__name__值为“__main__”。可以根据这个特点,将模块源代码文件中的测试代码进行独立的处理。例如:
"""
本模块用于计算公司员工的薪资
"""
company = "同福客栈"
def yearSalary(monthSalary):
'''根据传入的月薪,计算出年薪'''
return monthSalary*12
def daySalary(monthSalary):
'''根据传入的月薪,计算出日薪'''
return monthSalary/22.5
if __name__=="__main__": #测试代码
print(yearSalary(3000))
print(daySalary(3000))
1.2 模块的导入
1.2.1 import 语句导入
import 语句的基本语法格式如下:
import 模块名 #导入一个模块
import 模块1,模块2… #导入多个模块
import 模块名 as 模块别名 #导入模块并使用新名字
import 本质上是使用了内置函数__import__()。通过import 导入一个模块后,最终会生成一个module 类对象,代表被加载的模块。
1.2.2 from…import 导入
用于导入模块中的成员,基本语法格式如下:
from 模块名 import 成员1,成员2,…
若希望导入一个模块中的所有成员,可采用如下方式:
from 模块名 import * (但应尽量避免使用)
【注】import 导入的是模块。而 from...import 导入的是模块中的一个函数/类,可直接使用这些类/函数,前面无需添加“模块名称”。
1.2.3 使用 importlib 模块实现动态导入
import importlib
a = importlib.import_module("math")
print(a.pi)
1.2.4 模块的加载
当导入一个模块时, 模块中的代码都将被执行。但若再次导入这个模块,则不会再次执行。
【重新加载】:若确实需要重新加载一个模块,可以使用:importlib.reload() 方法。
1.3 包(package)
当一个项目包含多个模块时,将功能类似的模块组织在一起,就形成了“包”。包可以包含“模块(module)”,也可以再包含“子包(subpackage)”。
1.3.1 导入包
若需导入a包的aa子包中的模块module_AA.py,可使用如下方式:
1)import a.aa.module_AA
在使用时,必须引用完整名称,比如:a.aa.module_AA.fun_AA()
2)from a.aa import module_AA
在使用时,可以直接引用模块名,比如:module_AA.fun_AA()
3)from a.aa.module_AA import fun_AA
在使用时,可以直接引用函数名,比如:fun_AA()
【注】
1)语法 from package import item 中,item 可以是包、模块,也可以是函数、类、变量。
2)语法 import item1.item2 中,item 必须是包或模块,不能是其他。
1.3.2 __init__.py 文件
__init__.py 的三个核心作用:
1)作为包的标识,不能删除;
2)实现模糊导入;
3)导入包的操作实质就是执行__init__.py 文件,__init__.py 文件中可以涵盖包的初始化、需要统一执行的代码等,实现批量导入。
1.3.3 用 * 导入包(模糊导入)
import * 理论上是希望文件系统找出包中所有的子模块,然后将其导入。但 Python 中可以实现明确的包索引。
可在__init__.py 中定义__all__ 变量,该变量为一列表。如在__init__.py 中,定义__all__ = ["module_A","module_A2"],这意味着, from sound.effects import * 会从对应的包中导入以上两个子模块。
1.3.4 包内引用
若在子包内进行引用,可以根据相对位置引入子模块。例如:
from .. import module_A # .. 表示上级目录
from . import module_A2 # . 表示同级目录
1.3.5 sys.path 和模块搜索路径
当导入某个模块文件时, Python 解释器一般按照如下路径寻找模块文件(按照顺序寻找,找
到即停不继续往下寻找):
1)内置模块
2)当前目录
3)程序的主目录
4)pythonpath 目录(如果已经设置了pythonpath 环境变量)
5)标准链接库目录
6)第三方库目录(site-packages 目录)
7).pth 文件的内容(如果存在的话)
8) sys.path.append()临时添加的目录
2. 异常机制
2.1 try...except 结构
try:
被监控的可能引发异常的语句块
except BaseException [as e]:
异常处理语句块
try 块包含可能引发异常的代码,except 块用来捕捉和处理发生的异常。执行时,若 try 块中没有引发异常,则跳过ecept 块继续执行后续代码;若 try块中发生了异常,则跳过try 块中的后续代码,到相应的except 块中处理异常;异常处理完后,继续执行后续代码。
2.2 try...多个except 结构
try:
被监控的、可能引发异常的语句块
except Exception1: #按照先子类后父类的顺序
处理Exception1 的语句块
except Exception2:
处理Exception2 的语句块
...
except BaseException:
处理可能遗漏的异常的语句块
2.3 try...except...else 结构
若 try 块中没有抛出异常,则执行else 块;否则,执行except 块,不执行else 块。
2.4 try...except...finally 结构
在 try...except...finally 结构中,finally 块无论是否发生异常都会被执行,通常用来释放try 块中
申请的资源。
try:
f = open("d:/a.txt",'r')
content = f.readline()
print(content)
except BaseException as e:
print(e)
finally:
f.close() #释放资源。此处也可能会发生异常,若发生异常,则程序终止,不会继续往下执行。
print("step4")
2.5 return 语句
一般不把return 放到异常处理结构中,而是放到方法的最后。
def test01():
print("step1")
try:
x = 3/0
except:
print("step2")
print("异常:0 不能做除数")
finally:
print("step4")
print("step5")
return "e" #一般不将return语句放在try、except、else、finally块中,而放到方法最后。
print(test01())
2.6 traceback 模块
#使用traceback 将异常信息写入日志文件
import traceback
try:
print("step1")
num = 1/0
except:
with open("a.txt","w") as f:
traceback.print_exc(file=f)
'''
a.txt文件信息:
Traceback (most recent call last):
File "D:/Softwares/PycharmProjects/MyDemo/day09/03.py", line 15, in <module>
num = 1/0
ZeroDivisionError: division by zero
'''
2.7 自定义异常类
自定义异常类通常继承Exception 或其子类,命名时一般以 Error、Exception 为后缀。
自定义异常由raise 语句主动抛出。
#测试自定义异常类
class AgeError(Exception): #继承Exception
def __init__(self,errorInfo):
Exception.__init__(self)
self.errorInfo = errorInfo
def __str__(self):
return str(self.errorInfo)+"年龄错误!应在1-150之间"
if __name__=="__main__":
age = int(input("请输入年龄:"))
if age<1 or age>150:
raise AgeError(age)
else:
print("正常的年龄:",age)
'''
请输入年龄:0
Traceback (most recent call last):
File "D:/Softwares/PycharmProjects/MyDemo/day09/04.py", line 21, in <module>
raise AgeError(age)
__main__.AgeError: 0年龄错误!应在1-150之间
'''