1. 生成器对象
# 本质其实还是迭代器 只不过是我们自己通过写代码产生
# 也是有__iter__和__next__方法
def index():
yield 666
# yield 666, 555
# print('6666!!!')
yield 666 # yield有点像return的功能
'''生成器对象也是节省存储空间的 特性与迭代器对象一致'''
"""
当函数体代码中含有yield关键字
第一次调用函数并不会执行函数体代码
而是将函数变成了生成器
如何验证?
是否有iter()和next()方法
"""
# 没有调用之前 就是一个普通的函数
print(index)
# >>><function index at 0x1096c0ea0>
# 加括号调用并接收结果:不执行代码 而是变成生成器对象(迭代器)
res = index()
print(res)
# >>><generator object index at 0x11da33468>
# 变成生成器对象之后调用__next__就会开始执行函数体代码
print(res.__next__())
# >>>123
print(res.__next__())
# >>>(123, 111)
print(res.__next__())
# >>>666
print(res.__next__())
# >>>报错 已经取完值了,然后就会报错了
for i in res:
print(i)
"""
如果函数体代码中含有多个yield关键字 执行一次__next__返回后面的值并且让代码停留在yield位置
再次执行__next__基于上次的位置继续往后执行到下一个yield关键字处
如果没有了 再执行也会报错 StopIteration
"""
2. 自定义range方法
# range方法其实是一个可迭代对象
for index in range(1, 10):
print(index)
'''
需求:通过生成器模拟range方法(课堂练习)
def my_range():
pass
for index in my_range(1,10):
print(index)
'''
# 先以两个参数的range方法为例
def my_range(end, start=0):
while start < end:
yield start
start += 1
for index in my_range(100, 1):
print(index)
# 初步功能实现之后 再去考虑不同参数的情况 一个参数 三个参数
# 针对一个参数情况
"""
start可以不传值,将其改为默认参数,默认为0
"""
for index in my_range(100):
print(index)
# 这对三个参数情况
"""
给函数添加第三个形参 并且设置成默认参数 默认值是1 move=1
每次递增的时候只需要递增move的数值即可
start += move
"""
def my_range(end, start=0, move=1):
if not end:
end = start
start = 0
while start < end:
yield start
start += move
for index in my_range(10):
print(index)
"""
写代码一定不要想太多 先搭建整体的框架与功能 之后再考虑对函数的优化
思路一定要清晰!!!
"""
3. yield关键字作用
# 1.在函数体代码中出现 可以将函数变成生成器
# 2.在执行过程中 可以将后面的值返回出去 类似于return
# 3.还可以暂停住代码的运行
# 4.还可以接收外界的传值(了解) send方法
def eat(name):
print(f'{name}准备干饭')
while True:
food = yield
print(f'{name}正在吃{food}')
res = eat('python_cat')
# 想执行一次代码 如果想执行多次直至结束 可以直接用for循环
res.__next__()
# >>>python_cat准备干饭
res.__next__()
# >>>python_cat正在吃None
res.__next__()
# >>>python_cat正在吃None
res.send('python cat')
# >>>python_cat正在吃python cat
# >>>可以给yield传值 并且自动调用一次__next__方法
res.send('python_cat')
# >>>python_cat正在吃python_cat
# >>>可以给yield传值 并且自动调用一次__next__方法
4. 生成器表达式
# 也是为了节省存储空间
# 在后期我们做代码优化的时候,可以考虑使用
res = (i for i in 'python_cat')
print(res)
# >>><generator object <genexpr> at 0x000002D486D5F890>
print(res.__next__())
# >>>p
"""生成器内部的代码只有在调用__next__迭代取值的时候才会执行"""
5. 模块
"""
python之所以很火并且适用于各行各业很大程度上的原因就是>>>:模块
import time 导入模块
time.time() 调用方法
作为一名python工程师 如果遇到一个非常复杂的功能需要实现 那么第一时间不是想着如何去写 而是去网上找有没有相应的python模块!!!
"""
# 1.什么是模块?
# 模块就是一系列功能的结合体 可以直接使用
# 2.为什么要用模块?
# 极大地提升开发效率(拿来主义>>>:站在巨人的肩膀上)
# 3.模块的三种来源
# 1.内置的模块
# 无需下载 解释器自带 直接导入使用即可
# 2.自定义模块
# 自己写的代码 封装成模块 自己用或者发布到网上供别人使用
# 3.第三方模块
# 别人写的发布到网上的 可以下载使用的模块(很多牛逼的模块都是第三方)
# 4.模块的四种表现形式
# 1.使用python代码编写的py文件
# 2.多个py文件组成的文件夹(包)
# 3.已被编译为共享库或DLL的c或C++扩展(了解)
# 4.使用C编写并链接到python解释器的内置模块(了解)
6. 模块的两种导入方式
"""要想使用模块 必须先导入 而导入的方法有两种"""
# 方式1>>>:import...句式
import python_cat
print(python_cat.name)
python_cat.read_index()
"""
前提:在研究模块的时候 一定要分清楚谁是执行文件 谁是被导入文件(模块)
模块简介.py是执行文件 python_cat.py是被导入文件(模块)
导入模块内部到底发送了什么事情
1.执行当前文件 产生一个当前文件的名称空间
2.执行import句式 导入模块文件(即执行模块文件代码产生模块文件的名称空间)
3.在当前文件的名称空间中产生一个模块的名字 指向模块的名称空间
4.通过该名字就可以使用到模块名称空间中的所有数据
ps:相同的模块反复被导入只会执行一次
import python_cat 有效
import python_cat 无效(写了跟没写一样)
import python_cat 无效(写了跟没写一样)
"""
# name = 'tony'
# print(python_cat.name)
# python cat 获取模块名称空间中的name
# print(name)
# tony 获取当前名称空间中的name
"""
import句式的特点
可以通过import后面的模块名点的方式 使用模块中所有的名字
并且不会与当前名称空间中的名字冲突(指名道姓)
"""
import python_cat
money = 666
python_cat.change()
print(money)
def read_index():
print('111')
python_cat.read_index()
# 方式2>>>:from...import...句式
from python_cat import name, money, read_index
print(name)
# python_cat
name = 'tony'
print(name)
# tony
print(money)
# >>>报错 from python_cat import name 只使用模块中的name名字
read_index()
"""
1.执行当前文件产生一个名称空间
2.执行导入语句 运行模块文件产生名称空间存放运行过程中的所有名字
3.将import后面的名字直接拿到当前执行文件中
"""
"""
1.重复导入也只会导入一次
2.使用模块名称空间中的名字不需要加模块名前缀 直接使用即可
3.但是from...import的句式会产生名字冲突的问题
在使用的时候 一定要避免名字冲突
4.使用from...import的句式 只能使用import后面出现的名字
from...import...可以简单的翻译成中文
从...里面拿...来用 没有提到的都不能用 指名道姓
"""
![]()
7. 导入补充
# 1.可以给模块起别名(使用频率很高)
'''比如模块名或者变量名很复杂 可以起别名简写'''
# import python_cat as pc
# print(pc.name)
# from python_cat import name as n
# print(n)
# 2.连续导入多个模块或者变量名
# import time, sys, python_cat
# from python_cat import name, print_python_cat
"""连续导入多个模块 这多个模块最好有相似的功能部分 如果没有建议分开导入
如果是同一个模块下的多个变量名无所谓!!!
"""
# import time
# import python_cat
# 3.通用导入
from python_cat import *
'''*表示python_cat里面所有的名字 from...import的句式也可以导入所有的名字
如果模块文件中使用了__all__限制可以使用的名字 那么*号就会失效 依据__all__后面列举的名字
'''
print(name)