今日总结

  • 生成器对象

  • 自定义range方法

  • yield关键字作用

  • 生成器表达式

  • 模块

  • 模块的两种导入方法

  • 导入补充

生成器对象(自定义迭代器)

本质还是迭代器 只不过是我们自己用过写代码产生
也是用__iter__和__next__方法
Python的for语句循环本质上就是通过调用可迭代对象的__iter()__方法获得一个迭代器对象,然后不断调用迭代器对象__next()__方法实现的。迭代器对象则是一个需要实现__iter__()和__next__()两个迭代器协议方法的对象。python中生成器提供了一种方便的方法来实现迭代器协议,而不需要必须实现__iter__()和__next__()两个迭代器协议方法。
def index():
  print('你还记得我吗?')
  yield 123
  yield 123, 111
  print('是不是忘记我了!!!')
  yield 666


"""
当函数体内含有yield关键字 那么在第一次调用函数的时候
并不会执行函数体代码 而是将函数变成了生成器(迭代器)
"""
"""
如果函数体代码中含有多个yield关键字 执行一次__next__返回后面的值并且让代码停留在yield位置
再次执行__next__基于上次的位置继续往后执行到下一个yield关键字处
如果没有了 再执行也会报错 StopIteration
"""

自定义range方法

range方法其实是一个可迭代对象

'''
需求:通过生成器模拟range方法
def my_range():
pass
for i in my_range(1,10):
print(i)
'''

yield关键字作用

1.在函数体代码中出现 可以将函数变成生成器
2.在执行过程中 可以将后面的值返回出去 类似return
3.还可以暂停住代码的运行
4.还可以接收外界的传值

def eat(name):
print(f'{name}打游戏')
while True:
action = yield
print(f'{name}去洗脚城{action}')
res = eat('jason')
# 执行一次代码 如果想执行多次直至结束 可以直接用for循环
res.__next__() # jason打游戏
res.__next__() # jason去洗脚城None
res.__next__() # jason去洗脚城None
res.__next__() # jason去洗脚城None
res.__next__() # jason去洗脚城None
res.send('买中药') # jason去洗脚城买中药
#可以给yield传值 并且自动调用一次__next__方法
yield跟return对比
yield
1.可以返回值(支持多个并且组成元组)
  2.函数体代码遇到yield不会结束而是‘停住’
  3.yield可以将函数变成生成器 并且还支持外界传值
return
1.可以返回值(支持多个并且组织成元组)
  2.函数体代码遇到return直接结束

生成器表达式

也是为了节省存储空间
res = (i for i in 'faker')
print(res) # <generator object <genexpr> at 0x0000021A0DD2AA98>
print(res.__next__())
'''生成器内部的代码只有在调用__next__迭代值的时候才会执行'''

模块

1.什么是模块?
模块就是一系列功能的结合体 可以直接使用
2.为什么要使用模块?
极大的提升开发效率
3.模块的三大来源
1.内置的模块
无需下载 解释器自带 直接导入使用即可
2.自定义模块
自己写的代码 封装成模块 自己用或者发布到网上供别人使用
3.第三方模块
别人写的发布到网上的 可以下载使用的模块
4.模块的四种表现形式
1.使用python代码编写py文件
2.多个py文件组成的文件夹(包)
3.已被编译为共享库DLL的c或C++扩展
4.使用C编写并链接到python解释器的内置模块

模块的两种导入方式

'''要想使用模块 必须先导入 导入的方法有两种'''
方式1:import...句式
import md
print(md.name)
md.read()

在研究模块的时候 一定要分清楚谁是执行文件 谁是被导入文件(模块)
导入模块内部到底发生了什么?
1.执行当前文件 产生一个当前文件的名称空间
2.执行import句式 导入模块文件(即执行模块文件代码产生模块文件的名称空间)
3.在当前文件的名称空间中产生一个模块的名字 指向模块的名称空间
4.通过该名字就可以使用到模块名称空间中的所有数据

相同的模块反复被导入只会执行一次
'''
import句式的特点
可以通过import后面的模块点名的方式 使用模块中所有的名字
并且不会与当前名称空间中的名字冲突
'''
方式2:from...import句式
from md import name,age,salary
print(name) # 模块里的name
name = 'faker'
print(name) # faker
'''
1.执行当前文件产生一个名称空间
2.执行导入语句 运行模块文件产生名称空间存放运行过程中的所有名字
3.将import后面的名字直接拿到当前执行文件中
'''
'''
1.重复导入也只会导入一次
2.使用模块名称空间中不需要加模块名前缀 直接使用即可
3.from...import的句式会产生名字冲突的问题
在使用的时候 一定要避免名字冲突
4.使用from...import的句式 只能使用import后面出现的名字

导入补充

1.可以给模块起别名
模块名或者变量名很复杂 可以起别名简写
import ahbkjfbskdbf as a
print(a.name)
2.连续导入多个模块或者变量名
import time sys m
from m import name,age,salary
3.通用导入
from m import *
'''
*表示m中所有的名字 from...import的句式也可以导入所有的名字
如果模块文件中使用了__all__限制可以使用的名字 那么*号就会失效 依据__all__后面理解列举的名字
'''

 

 

 



 posted on 2022-03-24 23:18  鳗鱼的春天  阅读(12)  评论(0编辑  收藏  举报