[toc]
模块 Module
定义
包含一系列数据、函数、类的文件,通常以.py结尾。
作用
让一些相关的数据,函数,类有逻辑的组织在一起,使逻辑结构更清晰
导入
Import
- 语法:
import 模块名import 模块名 as 别名
- 作用:将某模块整体导入到当前模块中
- 使用:
模块名.成员
from import
- 语法:
from 模块 import 成员们 [as 别名1]
- 作用:将模块内的一个或多个成员导入到当前模块的作用域中。
from import *
- 语法:
from 模块名 import * - 作用:将某模块的所有成员导入到当前模块。
- 模块中一下划线(_)开头的属性,不会比导入,通常称这些成员为隐藏成员。
模块变量
__all__变量:定义可导出成员,仅对from xx import *语句有效。__doc__变量:文档字符串__file__变量:模块对应的文件路径名__name__变量:模块自身名字,可以判断是否为主模块- 当此模块作为主模块(第一个运行的模块)运行时,
__name__绑定“__main__”,不是主模块,而是被其他模块导入时,存储模块名
- 当此模块作为主模块(第一个运行的模块)运行时,
加载过程
在模块导入时,模块的所有语句会执行。如果一个模块已经导入,则再次导入时不会重新执行模块内的语句
分类
- 内置模块(builtins),在解析器的内部可以直接使用。
- 标准库,安装python时已安装且可直接使用。
- 第三方模块(通常为开源),需要自己安装。
- 用户自己编写的模块(可以作为其他人的第三方模块)
搜索顺序
搜索内建模块(builtins)
sys.path提供的路径,通常第一个是程序运行时的路径。
包 Package
定义
将模块以文件夹的形式进行分组管理。
作用
让一些相关的模块组织在一起,是逻辑结构更加清晰。
导入
from 包名 import 模块名 [as 模块新名]from 包名.子包名 import 模块名 [as 模块新名]from 包名.子包名.模块名 import 成员名 [as 属性新名]from 包名 import *from 包名.模块名 import *
搜索顺序

sys.path提供的路径
__init__.py文件是包内必须存在的文件
会在包加载时被自动调用
异常处理 Error
异常
- 定义:运行时检测到的错误。
- 现象:当异常发生时,程序不会在向下执行,而转到函数的调用语句
- 常见异常类型:
- 名称异常(NameError):变量未定义。
- 类型异常(TypeError):不同类型数据进行运算。
- 索引异常(IndexError):超出索引范围。
- 属性异常(AttributeError):对象没有对应名称的属性。
- 键异常(KeyError):没有对应名称的键。
- 实现异常(NotImplementedError):尚未实现的方法。
- 异常基类Exception。
处理
1.语法:
try:
# 可能出发异常的语句
except 错误类型 1 [as 变量 1]
处理语句1
except 错误类型 2 [as 变量 2]
处理语句2
except Exception [as 变量 3]:
不是以上错误类型的语句
else:
未发生异常执行的语句
finally:
无论是否发生异常的语句
2.作用:将程序由异常状态转为正常流程。
3.说明:
- as自居适用于绑定错误对象的变量,可以省略。
- except字句可以有一个或多个,用来捕获某种类型的错误。
- else字句最多只能有一个。
- finally字句最多只能有一个,如果没有except字句,必须存在。
- 如果异常没有被捕获到,会向上层(调用处)继续传递,直到程序终止运行
rasie语句
- 作用:跑出一个错误,让程序进入异常状态。
- 目的:在程序调用层数较深时,向主调函数传递错误信息要层层return比较麻烦,所以人为抛出异常,可以直接传递错误信息
自定义异常
1.定义
class 类名 Error(Exception):
def __init__(self,参数):
super().__init__(参数)
self.数据 = 参数
2.调用:
try:
...
rasie 自定义异常类名(参数)
...
except 定义异常类 as 变量名:
变量名.数据
3.作用:封装错误信息
4.代码示例:
"""
自定义异常
练习:成绩异常(1-100)
"""
class AgeError(Exception):
"""
封装错误信息
"""
def __init__(self, msg, code, age_value):
super().__init__(msg)
self.msg = msg
self.code = code
self.age_value = age_value
class Wife:
def __init__(self, age):
self.age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if 20 <= value <= 30:
self.__age = value
else:
# print("我不要")
# raise ValueError("我不要") # 人为抛出异常
raise AgeError("我不要", 27, value)
try:
w01 = Wife(80)
print(w01.age)
except AgeError as e:
print("错误信息:", e.msg)
print("错误代码行号:", e.code)
print("输入的年龄是:", e.age_value)
迭代
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
可迭代对象iterable
1.定义:具有__iter__函数的对象,可以返回迭代器对象。
2.语法:
创建:
class 可迭代对象名称:
def __iter__(self):
return 迭代器
使用:
for 变量名 in 可迭代对象:
语句
3.原理
迭代器 = 可迭代对象.__iter__()
while True:
try:
print(迭代器.__next__())
except StopIteration:
break
4.代码示例
"""
可迭代对象:具有__iter()__方法,可以返回迭代器对象的对象。
"""
list01 = [1, 2, 4, 5]
# for i in list01:
# print(i)
# 面试题
# 能够被for循环的条件是:可迭代对象(具有__iter()__方法的对象)
# for循环原理
# 1. 获取迭代器对象。
# 2. 循环迭代(调用迭代器的__next()__方法)
# 3. 捕获StopIteration异常
# 1.
iterator = list01.__iter__()
# 2.
# item = iterator.__next__()
# print(item)
# item = iterator.__next__()
# print(item)
# item = iterator.__next__()
# print(item)
# item = iterator.__next__()
# print(item)
# 3.
# item = iterator.__next__()
# print(item)
# 错误 :StopIteration --> 停止迭代
# 1.获取迭代器对象。
iterator = list01.__iter__()
while True:
try: # 如果获取了全部元素,则执行except
# 2. 获取下一个元素(迭代过程)
iterator.__next__()
# 3. 停止迭代(StopIteration)
except StopIteration:
break # 退出循环体
迭代器对象iterator
1.定义:可以被next()函数调用并返回下一个值的对象。
2.语法
class 迭代器类名:
def __init__(self,聚合对象):
self.聚合对象 = 聚合对象
def __next__(self):
if 没有元素:
raise StopIteration
return 聚合对象元素
3.说明:聚合对象通常是容器对象
4.作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又无需了解其内部结构。
5.代码示例
"""
迭代器
"""
class Skill:
pass
class SkillIterator:
def __init__(self, target):
self.target = target
self.index = 0
def __next__(self):
# 如果越界则抛出异常
if self.index >= len(self.target):
raise StopIteration
# 返回下一个元素
item = self.target[self.index]
self.index += 1
return item
class SkillManager:
def __init__(self, skills):
self.skills = skills
def __iter__(self):
# 创建迭代器对象,传递需要迭代的数据
return SkillIterator(self.skills)
manager = SkillManager([Skill(), Skill(), Skill()])
# for item in manager.skills:
# # for item in manager: # TypeError: 'SkillManager' object is not iterable
# print(item)
# iterator = manager.__iter__()
# while True:
# try:
# item = iterator.__next__()
# print(item)
# except StopIteration:
# break
for i in manager:
print(i)
6. 一个更深次的练习
"""
迭代器 --> yield
练习:exercise04/exercise05
"""
class Skill:
pass
# class SkillIterator:
# """
# 技能迭代器
# """
# def __init__(self, target):
# self.target = target
# self.index = 0
#
# def __next__(self):
# if self.index > len(self.target) - 1:
# raise StopIteration()
# item = self.target[self.index]
# self.index += 1
# return item
class SkillManager:
def __init__(self, skills):
self.skills = skills
# def __iter__(self):
# return SkillIterator(self.skills)
def __iter__(self):
"""
执行过程:
1.调用__iter__()方法不执行
2.调用__next__()方法时执行,到yield语句暂时离开.
3.再次调用__next__()方法时,从上次离开的代码开始执行,到yield语句暂时离开
4. 待执行完方法体,抛出StopIteration异常.
原理:如果方法体中包含yield关键字,那么会自动生成迭代器对象.
生成迭代器代码的大致规则:
1. 将yield关键字以前的代码,放到__next__方法中.
2. 将yield关键字以后的数据,作为__next__方法的返回值
"""
# print("准备返回第一个元素")
# yield self.skills[0] # 暂时离开点 再次执行点
#
# print("准备返回第二个元素")
# yield self.skills[1]
#
# print("准备返回第三个元素")
# yield self.skills[2]
for item in self.skills:
yield item
#---------------以下是客户端代码---------------------
manager = SkillManager([Skill(), Skill(), Skill()])
# for item in manager:
# print(item)
iterator = manager.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except Exception as e:
print(e)
break
生成器generator
- 定义:能够动态(循环一次计算一次返回一次)提供数据的可迭代对象。
- 作用:在循环过程中,按照某种算法推算数据,不必创建容器存储结果,从而节省内存空间。数据量越大,优势越明显。
- 以上作用也称之为延迟操作或者惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次构建出所有结果。
生成器函数
1.定义:含有yield语句的函数,返回值为生成器对象。
2.语法
-- 创建: def 函数名(): … yield 数据 … -- 调用: for 变量名 in 函数名(): 语句
3.说明
- 调用生成器函数将返回一个生成器对象,不执行函数体。
- yield翻译为”产生”或”生成”
4.执行过程
- 调用生成器函数会自动创建迭代器对象。
- 调用迭代器对象的__next__()方法时才执行生成器函数。
- 每次执行到yield语句时返回数据,暂时离开。
- 待下次调用__next__()方法时继续从离开处继续执行。
5.原理:生成迭代器对象的大致规则如下
- 将yield关键字以前的代码放在next方法中
- 将yield关键字后面的数据作为next方法的返回值。
6.特点:惰性操作/延迟操作(循环一次,计算一次,返回一次.)
7.本质: 迭代器 + 可迭代对象
内置生成器
枚举函数enumerate
- 语法:
for 变量 in enumerate(可迭代对象):
语句
for 索引, 元素in enumerate(可迭代对象):
语句
- 作用:遍历可迭代对象时,可以将索引与元素组合为一个元组。
zip
- 语法:
for item in zip(可迭代对象1, 可迭代对象2….):
语句
- 作用:将多个可迭代对象中对应的元素组合成一个个元组,生成的元组个数由最小的可迭代对象决定。
生成器表达式
- 定义:用推导式形式创建生成器对象。
- 语法:变量 = ( 表达式 for 变量 in 可迭代对象 [if 真值表达式] )
函数式编程
- 定义:用一系列函数解决问题。
- 函数可以赋值给变量,赋值后变量绑定函数。
- 允许将函数作为参数传入另一个函数。
- 允许函数返回一个函数。
- 高阶函数:将函数作为参数或返回值的函数。
函数作为参数
将核心逻辑传入方法体,使该方法的适用性更广,体现了面向对象的开闭原则

一个简单的函数作为参数的示例
lambda 表达式
- 定义: 是一种匿名方法
- 作用:作为参数传递时语法简洁,优雅,代码可读性强。随时创建和销毁,减少程序耦合度。
- 说明:
- 形参没有可以不填
- 方法体只能有一条语句,且不支持赋值语句。
- 语法:
-- 定义: 变量 = lambda 形参: 方法体 -- 调用: 变量(实参)
lambda表达式的实际应用

内置高阶函数
- map(函数,可迭代对象):使用可迭代对象中的每个元素调用函数,将返回值作为新可迭代对象元素;返回值为新可迭代对象。
- filter(函数,可迭代对象):根据条件筛选可迭代对象中的元素,返回值为新可迭代对象。
- sorted(可迭代对象,key = 函数,reverse = bool值):排序,返回值为排序结果。
- max(可迭代对象,key = 函数):根据函数获取可迭代对象的最大值。
- min(可迭代对象,key = 函数):根据函数获取可迭代对象的最小值。
函数作为返回值
闭包
- 三要素
- 必须有一个内嵌函数。
- 内嵌函数必须引用外部函数中变量。
- 外部函数返回值必须是内嵌函数。
- 定义:在一个函数内部的函数,同时内部函数又引用了外部函数的变量。
- 本质:闭包是将内部函数和外部函数的执行环境绑定在一起的对象。
- 优点:内部函数可以使用外部变量。
- 缺点:外部变量一直存在于内存中,不会在调用结束后释放,占用内存。
- 作用:实现python装饰器。
- 语法:
def fun01():
print("fun01执行喽")
a = 1
def fun02():
print("fun02执行喽")
print("外部变量是:", a)
return fun02
# 得到的是内部函数
result = fun01()
# 调用内部函数,因为内部函数使用了外部变量,所以称之为闭包.
result() # 可以使用外部变量,说明外部函数在调用后没有释放.
# 案例:
def give_gift_money(money):
"""
获取压岁钱
"""
print("得到了%d压岁钱" % money)
def child_buy(target, price):
"""
孩子需要买东西
"""
nonlocal money
if money >= price:
money -= price
print("孩子花了%d钱,买了%s,还剩下%d钱." % (price, target, money))
else:
print("压岁钱不够了")
return child_buy
action = give_gift_money(10000)
action("98k", 3500)
action("小猪佩奇", 300)
action("大黄蜂", 8000)
# 体会:闭包使得逻辑连续(因为内部函数可以使用外部变量).
函数装饰器decorators
定义:在不改变原函数的调用以及内部代码情况下,为其添加新功能的函数。
本质:使用“@函数装饰器名称”修饰原函数,等同于创建与原函数名称相同的变量,关联内嵌函数;故调用原函数时执行内嵌函数。
原函数名称 = 函数装饰器名称(原函数名称)
装饰器链:
一个函数可以被多个装饰器修饰,执行顺序为从近到远。
语法
装饰器的调用过程
