模块 Module 包含一系列数据、函数、类的文件,通常以.py结尾。
作用:让一些相关的数据,函数,类有逻辑的组织在一起,使逻辑结构更加清晰。有利于多人合作开发。
import
(1) 语法
import 模块名
import 模块名 as 别名
(2) 作用:将模块整体导入到当前模块中
(3) 使用:模块名.成员
from import
(1) 语法:
from 模块名 import 成员名
from 模块名 import 成员名 as 别名
from 模块名 import *
(2) 作用:将模块内的成员导入到当前模块作用域中
(3) 使用:直接使用成员名
#module01.py
def func01():
print("func01执行了")
def func02():
print("func02执行了")
# "我过去"
# 语法:import 模块名
# 使用:模块名.成员
# 本质:创建文件,关联目标模块地址
import module01 #pycharm上在模块共同的目录上右键,Mark directory as ,Sources root
module01.func01()
module01.func02()
# "你过来"
# 语法:from 模块名 import 成员
# 直接使用成员
# 本质:将目标模块中的成员导入到当前模块作用域中
# 注意:小心命名冲突,程序自上而下
# from module01 import func01
# from module01 import func01,func02
from module01 import *
func01() #func01执行了
def func01():
print("dmoe05-func01")
func01() #dmoe05-func01
#module_exercise.py
data = 100
def func01():
print("func01执行喽")
class MyClass:
def func02(self):
print("func02执行喽")
@classmethod
def func03(cls):
print("func03执行喽")
print(__name__)
# 导入方式1:导入文件
# 适用性:面向过程的技术(全局变量/函数)
import module_exercise
print(module_exercise.data)
module_exercise.func01()
# 通过对象访问实例方法
m = module_exercise.MyClass()
m.func02()
module_exercise.MyClass.func03()
# 导入方式2:导入文件中的成员
# 适用性:面向对象的技术(类)
from module_exercise import *
print(data)
func01()
m = MyClass()
m.func02()
MyClass.func03()
将信息管理系统拆分为4个模块student_info_manager_system.py
(1)创建目录student_info_manager_system
(2)创建模块bll,存储XXController
业务逻辑层 business logic layer
(3)创建模块usl,存储XXView
用户显示层 user show layer
(4)创建模块model,存储XXModel
(5)创建模块main,存储调用XXView的代码
#bll.py
from model import StudentModel
class StudentController:
"""
学生控制器:处理核心功能,存储...
"""
__start_id = 100 # 大家的:系统不同界面使用的学生编号是一份(连续增加)
@classmethod
def __set_student_id(cls, stu):
cls.__start_id += 1
stu.sid = cls.__start_id
def __init__(self):
self.__list_student = [] # 自己的:系统不同界面使用自己数据(可以显示不同数据)
@property # 只读属性:View类只能读取,不能修改
def list_student(self):
return self.__list_student
def add_student(self, new_stu):
# 设置学生编号
StudentController.__set_student_id(new_stu)
# 追加到列表中
self.__list_student.append(new_stu)
def remove_student(self, sid):
"""
在列表中删除学生信息
:param sid: 学生编号
:return: 是否成功
"""
stu = StudentModel(sid=sid)
if stu in self.__list_student:
# 重写Model类的eq方法
self.__list_student.remove(stu)
return True
return False
def update_student(self, stu):
"""
:param stu:
:return:
"""
for i in range(len(self.__list_student)):
if self.__list_student[i].sid == stu.sid:
# self.list_student[i].name = stu.name
# self.list_student[i].age = stu.age
# self.list_student[i].score = stu.score
self.__list_student[i].__dict__ = stu.__dict__
return True
return False
def ascending_order(self):
self.__list_student.sort()
# 项目部署后,应该从main.py模块执行
# 变量__name__是bll
if __name__ == "__main__":
# 测试代码,main.py模块执行时,不会执行
controller = StudentController()
controller.add_student(StudentModel())
controller.add_student(StudentModel())
controller.add_student(StudentModel())
#usl.py
from bll import StudentController
from model import StudentModel
class StudentView:
"""
学生视图:输入/输出学生信息
"""
def __init__(self):
self.__controller = StudentController()
def __display_menu(self):
print("按1键录入学生信息")
print("按2键显示学生信息")
print("按3键删除学生信息")
print("按4键修改学生信息")
print("按5键根据成绩显示学生信息")
def __select_menu(self):
item = input("请输入选项:")
if item == "1":
self.__input_student()
elif item == "2":
# 先写出调用函数代码,再快捷键生成定义函数代码
# alt + 回车
self.__display_students()
elif item == "3":
self.__delete_student()
elif item == "4":
self.__set_student()
elif item == "5":
self.__order_by_score()
def __input_student(self):
stu = StudentModel()
stu.name = input("请输入学生姓名:")
stu.age = int(input("请输入学生年龄:"))
stu.score = int(input("请输入学生成绩:"))
self.__controller.add_student(stu)
def main(self):
while True:
self.__display_menu()
self.__select_menu()
def __display_students(self):
for item in self.__controller.list_student:
# print(f"{item.name}的编号是{item.sid},年龄是{item.age},成绩是{item.score}")
print(item)
def __delete_student(self):
sid = int(input("请输入需要删除的学生编号:"))
if self.__controller.remove_student(sid):
print("删除成功")
else:
print("删除失败")
def __set_student(self):
stu = StudentModel()
stu.sid = input("请输入学生编号:")
stu.name = input("请输入学生姓名:")
stu.age = int(input("请输入学生年龄:"))
stu.score = int(input("请输入学生成绩:"))
if self.__controller.update_student(stu):
print("修改成功")
else:
print("修改失败")
def __order_by_score(self):
self.__controller.ascending_order()
self.__display_students()
#model.py
class StudentModel:
def __init__(self, name="", age=0, score=0.0, sid=0):
self.name = name
self.age = age
self.score = score
self.sid = sid
# 两个学生对象是否相同的依据:编号
def __eq__(self, other):
return self.sid == other.sid
# 两个学生对象大小的依据:成绩
def __gt__(self, other):
return self.score > other.score
# 显示学生的风格
def __str__(self):
return f"{self.name}的编号是{self.sid},年龄是{self.age},成绩是{self.score}"
#main.py
from usl import StudentView
# 如果是主模块才执行
# 快捷键:main+回车
if __name__ == '__main__':
# (被导入时不执行)
view = StudentView()
#光标停留StudentView(类名要正确),alt+enter -- import this name,选择usl的
view.main()
在模块导入时,模块的所有语句会执行。如果一个模块已经导入,则再次导入时不会重新执行模块内的语句。
__doc__变量: 注释的文档字符串。
__name__变量:模块自身名字,可以判断是否为主模块。
当此模块作为主模块(第一个运行的模块)运行时,name绑定'__main__',不是主模块,而是被其它模块导入时,存储模块名。
#module_exercise.py
data = 100
def func01():
print("func01执行喽")
class MyClass:
def func02(self):
print("func02执行喽")
@classmethod
def func03(cls):
print("func03执行喽")
print(__doc__) #注释的文档字符串
# 存储模块名称
print(__name__) # __main__
#在别的文件里导入上面的module_exercise模块时
import module_exercise
#module_exercise被其它模块导入时,不是主模块,导入时运行,print(__name__)打印的是存储的是模块名module_exercise
#module_exercise.py
data = 100
...
if __name__ == '__main__':
print(__name__)
import module_exercise
#运行时,import执行模块,__name__为module_exercise,不满足if 将不会打印print(__name__)
"""
小明使用手机打电话
面向对象三大特征:
封装:创建Person/MobilePhone/Landline类
继承:创建Communication统一MobilePhone/Landline的行为
隔离Person与MobilePhone/Landline的变化
多态:MobilePhone/Landline重写Communication类dialing方法,实现具体功能
编码时Person调用Communication
运行时Person调用MobilePhone/Landline
"""
class Person:
def __init__(self, name=""):
self.name = name
def call(self, communication):
print(self.name, "打电话")
# 调用交通工具
# 执行手机座机
communication.dialing()
class Communication:
def dialing(self):
pass
class MobilePhone(Communication):
def dialing(self):
print("手机呼叫")
class Landline():
def dialing(self):
print("座机呼叫")
xm = Person("小明")
xm.call(MobilePhone())
xm.call(Landline())
"""
玩家攻击敌人,敌人受伤,还可能死亡(加分)
(头顶爆字,扣除血量)
敌人攻击玩家,玩家受伤,还可能死亡(游戏结束)
(闪现红屏,扣除血量)
"""
class Character:
def __init__(self, hp, atk):
self.hp = hp
self.atk = atk
# 子类完全相同
def attack(self, target):
print("发起攻击")
target.damage(self.atk)
# 子类部分相同
def damage(self, value):
self.hp -= value
if self.hp <= 0:
self.death()
# 子类完全不同
def death(self):
pass
class Player(Character):
def damage(self, value):
print("闪现红屏")
super().damage(value)
def death(self):
print("游戏结束")
class Enemy(Character):
def damage(self, value):
print("头顶爆字")
super().damage(value)
def death(self):
print("加分")
p = Player(100, 25)
e = Enemy(50, 10)
p.attack(e)
e.attack(p)
p.attack(e)
(1) 内置模块(builtins),在解析器的内部可以直接使用。
(2) 标准库模块,安装Python时已安装且可直接使用。
(3) 第三方模块(通常为开源),需要自己安装。
(4) 用户自己编写的模块(可以作为其他人的第三方模块)
了解time模块使用
"""
标准库 - time
"""
import time
# 1. 人类时间: 0 ~ 至今
# 秦始皇统一中国:-221
# 时间元组(年,月,日,时,分,秒,星期,年的第几天,夏令时偏移量)
time_tuple = time.localtime()
print(time_tuple)
#time.struct_time(tm_year=2023, tm_mon=4, tm_mday=1, tm_hour=17, tm_min=19, tm_sec=13, tm_wday=5, tm_yday=91, tm_isdst=0)
# 获取星期
print(time_tuple[6]) #5
print(time_tuple[-3]) #5
print(time_tuple.tm_wday) #5
# 获取年月日
print(time_tuple[:3]) #(2023, 4, 1)
# 获取时分秒
print(time_tuple[3:6]) #(17, 25, 52)
# 2. 机器时间
# 时间戳:从1970年元旦到现在经过的秒数
print(time.time()) # 1680341152.8060458
# 3. 时间戳 <--> 时间元组
# 时间元组 = time.localtime(时间戳)
print(time.localtime(1680341152.8060458))
#time.struct_time(tm_year=2023, tm_mon=4, tm_mday=1, tm_hour=17, tm_min=25, tm_sec=52, tm_wday=5, tm_yday=91, tm_isdst=0)
# 时间戳 = time.mktime( 时间元组 )
print(time.mktime(time_tuple)) #1680341351.0
print(time.mktime((1970, 8, 19, 10, 42, 0, 0, 0, 0))) #19881720.0
# 4. 时间元组 <--> 字符串
# 字符串 = time.strftime(格式,时间元组)
print(time.strftime("%y/%m/%d %H:%M:%S", time_tuple)) #23/04/01 17:38:50
print(time.strftime("%y年%m月%d日 %H:%M:%S", time_tuple)) #23年04月01日 17:38:50
# 2021年08月19日 10:48:06
print(time.strftime("%Y年%m月%d日 %H:%M:%S", time_tuple)) #2023年04月01日 17:38:50
# 时间元组 = time.strptime(字符串,格式)
print(time.strptime("2023年04月01日 17:38:50", "%Y年%m月%d日 %H:%M:%S")) #time.struct_time(tm_year=2023, tm_mon=4, tm_mday=1, tm_hour=17, tm_min=38, tm_sec=50, tm_wday=5, tm_yday=91, tm_isdst=-1)
练习
"""
练习1:定义函数,根据年月日,计算星期。
输入:2020 9 15
输出:星期二
"""
import time
def get_week(year, month, day):
"""
根据年月日获取星期
:param year: int类型,年份
:param month: int类型,月份
:param day: int类型,天
:return: str类型,星期
"""
# 年月日 --> 字符串
str_time = "%s-%s-%s" % (year, month, day)
# 字符串 --> 时间元组
tuple_time = time.strptime(str_time, "%Y-%m-%d")
# 时间元组 --> 星期
tuple_week = ("星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日")
week_index = tuple_time[6]
return tuple_week[week_index]
print(get_week(2021, 8, 19))
"""
练习2:定义函数,根据生日(年月日),计算活了多天.
输入:2010 1 1
输出:从2010年1月1日到现在总共活了多少天
"""
def get_birthday(year, month, day):
"""
:param year:
:param month:
:param day:
:return:
"""
# 时间戳 = time.mktime(时间元组)
time_birthday = time.mktime((year, month, day, 0, 0, 0, 0, 0, 0))
# 当前时间戳 - 生日时间戳
second = time.time() - time_birthday
return second / 60 / 60 / 24
print("%.0f" % get_birthday(2010, 1, 1))
包package,将模块以文件夹的形式进行分组管理。
"""
Python项目完整结构
根目录
包 #目录下带有 __init__.py 文件,封装包里的成员,在导入的时候体现
模块
类
函数
语句
main.py
"""
$ ls -R package01/
package01/:
__init__.py package02/
package01/package02:
__init__.py module01.py
# 绝对路径:从项目根目录开始
#方法一
import package01.package02.module01 as m #只能找到模块
m.func01()
#方法二
from package01.package02.module01 import func01 #找到模块里的成员
func01()
#光标停留到模块名上,ctrl +q 查看模块位置
#__init__.py 文件,设置,封装包里的成员,在导入的时候体现功能
from package01.package02.module01 import func01
#demon.py
from package01.package02 import func01
func01()
my_project02/
main.py
common/
__init__.py
list_helper.py
skill_system/
__init__.py
skill_manager.py
通过导入包的方式,在main.py中调用skill_manager.py中实例方法。
通过导入包的方式,在skill_manager.py中调用list_helper.py中类方法。
#common/
# __init__.py
from common.list_helper import C
# list_helper.py
class C:
@classmethod
def func03(cls):
print("C-func03")
#skill_system/
# __init__.py
from skill_system.skill_manager import A
# skill_manager.py
from common import C
C.func03()
class A:
def func01(self):
print("A - func01")
#main.py
# import skill_system #只能找到模块
#
# a = skill_system.A()
# a.func01()
from skill_system import A #找到模块里的成员
a = A()
a.func01()
"""
小结 - 程序结构
1. 项目根目录
包
模块
类
方法
main.py
2. 相关概念
根目录: 主模块所在文件夹
主模块: 第一次执行的模块,不会生成pyc文件.
3. 导入模块
import 模块
模块.成员
import 包.模块 as 别名
别名.成员
from 模块 import 成员
直接访问成员
from 模块 import * #(导入所有的成员)
直接访问成员
4. 导入包
备注:必须在包的__init__.py模块中提供成员
import 包
模块.成员
import 包.包 as 别名
别名.成员
from 包 import 成员
直接访问成员
from 包 import *
直接访问成员
5. 导入模块是否成功的唯一标准
导入路径 + 系统路径 = 真实路径
"""
import sys
print(sys.path)
作用:将程序由异常状态转为正常流程
as 子句是用于绑定错误对象的变量,可以省略
except子句可以有一个或多个,用来捕获某种类型的错误。
else子句最多只能有一个。
finally子句最多只能有一个,如果没有except子句,必须存在。
如果异常没有被捕获到,会向上层(调用处)继续传递,直到程序终止运行。
try:
可能触发异常的语句
except 错误类型1 [as 变量1]:
处理语句1
except 错误类型2 [as 变量2]:
处理语句2
except Exception [as 变量3]:
不是以上错误类型的处理语句
else:
未发生异常的语句
finally:
无论是否发生异常的语句
"""
异常处理
适用性:不处理语法错误,而是处理逻辑错误
目的:将异常状态(不断向上返回),
改为正常状态(继续向下执行)
核心价值:
保障程序按照既定流程执行,不紊乱
"""
# 方式1:包治百病(民间喜爱,使用最多) #try下的执行出错后执行except后的操作
def div_apple(apple_count):
try:
# ValueError str fload int
person_count = int(input("请输入人数:"))
# ZeroDivisionError
result = apple_count / person_count
print("每人分得%f个苹果" % result)
# except Exception:
except:
print("程序出错啦")
div_apple(10)
print("后续逻辑")
# 方式2:对症下药(官方建议),但是复杂
def div_apple(apple_count):
try:
# ValueError
person_count = int(input("请输入人数:"))
# ZeroDivisionError
result = apple_count / person_count
print("每人分得%f个苹果" % result)
except ValueError:
print("错误,输入的不是整数")
except ZeroDivisionError:
print("错误,输入的是零")
div_apple(10)
print("后续逻辑")
# 方式3: 无论是否异常,一定执行的逻辑
def div_apple(apple_count):
try:
person_count = int(input("请输入人数:"))
result = apple_count / person_count
print("每人分得%f个苹果" % result)
# 打开文件的操作
# 处理文件
except ZeroDivisionError:
print("错误,输入的是零")
finally:
# 关闭文件时,使用较多
print("分苹果结束")
div_apple(10)
print("后续逻辑")
# 方式4:没有错误执行的逻辑
def div_apple(apple_count):
try:
person_count = int(input("请输入人数:"))
result = apple_count / person_count
print("每人分得%f个苹果" % result)
except ValueError:
print("错误,输入的不是整数")
except ZeroDivisionError:
print("错误,输入的是零")
else:
print("分苹成功啦")
div_apple(10)
print("后续逻辑")
"""
练习:创建函数,在终端中录入int类型成绩。如果格式不正确,重新输入。
"""
def get_score():
while True:
try:
score = int(input("请输入成绩:"))
return score # 输入无误执行本行,退出函数
except:
print("输入有误,请输入整数")
score = get_score()
print("成绩是:%d" % score)
class StudentView:
"""
学生视图:输入/输出学生信息
"""
....
def __get_number(self,message): #设计成函数,调用
while True:
try:
number = int(input(message))
return number
except:
print("输入有误,请输入整数")
def __input_student(self):
stu = StudentModel()
stu.name = input("请输入学生姓名:")
# stu.age = int(input("请输入学生年龄:")) #原来的
stu.age = self.__get_number("请输入学生年龄:")
stu.score = self.__get_number("请输入学生成绩:")
self.__controller.add_student(stu)
作用:抛出一个错误,让程序进入异常状态。
目的:在程序调用层数较深时,向主调函数传递错误信息要层层return比较麻烦,所以人为抛出异常,可以直接传递错误信息。
"""
人为创造异常
异常产生的完整流程
1 --> 2 --> ... --> 3
接收消息 发送消息
except Exception as e: raise Exception()
"""
class Wife:
def __init__(self, name="", age=0): # 2
self.name = name
self.age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, value): # 3
if 20 <= value <= 30:
self.__age = value
else:
# raise发送错误消息
raise Exception("年龄超过范围", 1001)
while True:
try:
age = int(input("请输入年龄:"))
shuang_er = Wife("双儿", age) # 1
print(shuang_er.__dict__)
break
# 接收错误消息
except Exception as e:
print(e.args) #"年龄超过范围", 1001
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
"""
迭代 iteration: 每一次得到的结果会作为下一次的初始值
可迭代对象 iterable: 有__iter__函数,能够创造迭代器的对象
迭代器 iterator: 有__next__函数,实现迭代过程的对象
"""
#message = "我是齐天大圣孙悟空"
#for item in message:
# print(item) #我\n是\n齐...
# for循环原理
#message = "我是齐天大圣孙悟空"
#iterator = message.__iter__()
#item = iterator.__next__()
#print(item) #我
#item = iterator.__next__()
#print(item) #是 ....
# 1. 获取迭代器
iterator = message.__iter__()
while True:
try:
# 2. 计算下一个元素
item = iterator.__next__()
print(item)
# 3. 如果停止迭代,则结束循环
except StopIteration:
break
# 面试题:
# 对象能够参与for循环的条件是什么?
# 答:对象必须具备__iter__函数,对象必须是可迭代对象
"""
创建列表,使用迭代思想,打印每个元素.
"""
list01 = [34, 54, 54, 56, 7]
iterator = list01.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
"""
创建字典,使用迭代思想,打印每个键值对.
"""
# 面试题:不使用for循环,获取字典所有键值对.
dict01 = {"a": 34, "b": 54, "c": 54}
iterator = dict01.__iter__()
while True:
try:
key = iterator.__next__()
print(key, dict01[key])
except StopIteration:
break
"""
迭代器 练习(for循环原理)
需求:迭代自定义对象
"""
class StudentIterator: # 3 定义迭代器,创建next函数
def __init__(self, data):
self.__data = data
self.__index = -1
def __next__(self):
try:
self.__index += 1
return self.__data[self.__index] # 4 从第一个列表数据返回
except:
raise StopIteration() # 5 异常抛出处理
class StudentController: # 可迭代对象
def __init__(self):
self.__list_student = []
def add_student(self, stu):
self.__list_student.append(stu)
def __iter__(self):
return StudentIterator(self.__list_student) # 1 把列表给到迭代器处理
controller = StudentController()
controller.add_student("A")
controller.add_student("B")
controller.add_student("C")
#for 原理实现
# for item in controller:
# print(item)
iterator = controller.__iter__() # 1 需创建 iter函数,返回迭代器
while True:
try:
item = iterator.__next__() # 2 需创建迭代器
print(item) # A
except StopIteration: # 6 异常处理
break
练习
"""
遍历商品控制器
class CommodityController:
pass
controller = CommodityController()
controller.add_commodity("屠龙刀")
controller.add_commodity("倚天剑")
controller.add_commodity("芭比娃娃")
for item in controller:
print(item)
"""
class CommodityIterator: # 迭代器
def __init__(self,data):
self.__data = data
self.__index = -1
def __next__(self):
try:
self.__index += 1
return self.__data[self.__index]
except IndexError:
raise StopIteration()
class CommodityController: # 可迭代对象
def __init__(self):
self.__list_commodity = []
def add_commodity(self, cmd):
self.__list_commodity.append(cmd)
def __iter__(self):
return CommodityIterator(self.__list_commodity)
controller = CommodityController()
controller.add_commodity("屠龙刀")
controller.add_commodity("倚天剑")
controller.add_commodity("芭比娃娃")
# for item in controller:
# print(item)
iterator = controller.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
#小鸭子原则 #没父类,依然可以使用,灵活,别的语言不可以
# ------------------架构师--------------------
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self, position, vehicle):
print("去" + position)
vehicle.transport() # 调用鸭子的呱呱叫方法
# ------------------程序员--------------------
class Car: # 狗
def transport(self): # 呱呱
print("汽车在行驶")
class Airplane: # 猫
def transport(self): # 呱呱
print("飞机在飞行")
zl = Person("老张")
car = Car()
air = Airplane()
zl.go_to("东北", car)
zl.go_to("东北", air)
"""
#创建自定义range类,实现下列效果.
class MyRange:
pass
for number in MyRange(5):
print(number)# 0 1 2 3 4
"""
class MyRangeIterator:
def __init__(self, end):
self.__number = -1
self.__end = end
def __next__(self):
if self.__number < self.__end - 1:
self.__number += 1
return self.__number
raise StopIteration()
class MyRange:
def __init__(self, stop):
self.__stop = stop
def __iter__(self):
return MyRangeIterator(self.__stop)
# for number in MyRange(5):
# print(number)# 0 1 2 3 4
# 循环一次 计算一次 返回一次
# 每次都存储当前结果,释放之前结果 m_range = MyRange(9999999999999999)
m_range = MyRange(9)
iterator = m_range.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
(1) 定义:能够动态 (循环一次计算一次返回一次) 提供数据的可迭代对象。
(2) 作用:在循环过程中,按照某种算法推算数据,不必创建容器存储完整的结果,从而节省内存空间。数据量越大,优势越明显。以上作用也称之为延迟操作或惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次构建出所有结果。
(1) 定义:含有yield语句的函数,返回值为生成器对象。
# 创建:
def 函数名():
…
yield 数据
…
# 调用:
for 变量名 in 函数名():
语句
说明:
-- 调用生成器函数将返回一个生成器对象,不执行函数体。
-- yield翻译为”产生”或”生成”
执行过程:
a. 调用生成器函数会自动创建迭代器对象。
b. 调用迭代器对象的next()方法时才执行生成器函数。
c. 每次执行到yield语句时返回数据,暂时离开。
d. 待下次调用next()方法时继续从离开处继续执行。
原理:生成迭代器对象的大致规则如下
a. 将yield关键字以前的代码放在next方法中。
b. 将yield关键字后面的数据作为next方法的返回值。
"""
迭代器 --> yield
"""
class StudentController: # 可迭代对象
def __init__(self):
self.__list_student = []
def add_student(self, stu):
self.__list_student.append(stu)
def __iter__(self):
# 生成迭代器代码的大致规则:
# 1. 将yield之前的代码定义到__next__函数体中
# 2. 将yield之后的数据作为__next__函数返回值
index = 0
yield self.__list_student[index]
index += 1
yield self.__list_student[index]
index += 1
yield self.__list_student[index]
controller = StudentController()
controller.add_student("A")
controller.add_student("B")
controller.add_student("C")
# for item in controller:
# print(item)
iterator = controller.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
"""
yield --> 生成器函数
"""
"""
class MyRange:
def __init__(self, stop):
self.__stop = stop
def __iter__(self):
number = 0
while number < self.__stop:
yield number
number += 1
# for number in MyRange(5):
# print(number)# 0 1 2 3 4
# 循环一次 计算一次 返回一次
# 每次都存储当前结果,释放之前结果
m_range = MyRange(8)
iterator = m_range.__iter__()
while True:
try:
item = iterator.__next__()
print(item)
except StopIteration:
break
"""
"""
# 生成器的伪代码
class generator:# 生成器对象 = 可迭代对象 + 迭代器对象
def __iter__(self):# 可迭代对象
return self
def __next__(self):# 迭代器对象
产生数据
"""
def my_range(stop):
number = 0
while number < stop:
yield number
number += 1
# print(my_range(5)) #生成器对象
for item in my_range(5): #制作自己的range函数
print(item)
# result = my_range(9999999999999999999999999999999)
# iterator = result.__iter__()
# while True:
# try:
# item = iterator.__next__()
# print(item)
# except StopIteration:
# break
"""
生成器函数应用
"""
# 需求:定义函数,在列表中查找大于10的所有数字
list01 = [3, 34, 55, 6, 6, 78, 89]
# 传统思想: 创建容器存储所有结果
def find_number_gt_10():
list_data = []
for item in list01:
if item > 10:
list_data.append(item)
return list_data
result = find_number_gt_10()
for number in result:
print(number)
# 生成器思想:循环一次 计算一次 返回一次
def find_number_gt_10():
for item in list01:
if item > 10:
yield item
# 惰性 延迟
result = find_number_gt_10()
#print(result) #生成器对象
for number in result:
print(number) #34\n55\n78\n89
# 练习1:在列表中找出所有偶数
list01 = [43, 43, 54, 56, 76, 87, 98]
def find_all_even():
for item in list01:
if item % 2 == 0:
yield item
result = find_all_even()
for number in result:
print(number)
# 练习2:在列表中找出所有数字
list02 = [43, "悟空", True, 56, "八戒", 87.5, 98]
def find_all_number():
for item in list02:
# if type(item) == int or type(item) == float:
if type(item) in (int, float):
yield item
for number in find_all_number():
print(number)
class Employee:
def __init__(self, eid, did, name, money):
self.eid = eid # 员工编号
self.did = did # 部门编号
self.name = name
self.money = money
list_employees = [
Employee(1001, 9002, "师父", 60000),
Employee(1002, 9001, "孙悟空", 50000),
Employee(1003, 9002, "猪八戒", 20000),
Employee(1004, 9001, "沙僧", 30000),
Employee(1005, 9001, "小白龙", 15000),
]
# 定义函数,在员工列表中查找编号是1003的员工
def find_employee_by_eid():
for item in list_employees:
if item.eid == 1003:
return item #只有一个对象,用return
emp = find_employee_by_eid()
print(emp.__dict__)
# 定义函数,在员工列表中查找部门是9001的所有员工
def find_employees_by_did():
for item in list_employees:
if item.did == 9001:
yield item #多个对象用yield
generator = find_employees_by_did()
for item in generator:
print(item.__dict__)
# 定义函数,在员工列表中查找薪资最高的员工
def get_max_by_money():
max_value = list_employees[0]
for i in range(1, len(list_employees)):
if max_value.money < list_employees[i].money:
max_value = list_employees[i]
return max_value
emp = get_max_by_money()
print(emp.__dict__)
# 定义函数,在员工列表中查找所有薪资大于20000的员工姓名
def find_names_by_money():
for item in list_employees:
if item.money > 20000:
yield item.name
for item in find_names_by_money():
print(item)