生成器与模块

生成器对象

# 本质其实还是迭代器 只不过是我们自己通过写代码产生
	也是有__iter__和__next__方法
    def index():
    # print('你还记得我吗?')
    yield 123
    yield 123, 111
    print('是不是忘记我了!!!')
    yield 666
'''生成器对象也是节省存储空间的 特性与迭代器对象一致'''
"""
当函数体代码中含有yield关键字
    第一次调用函数并不会执行函数体代码
    而是将函数变成了生成器
"""
res = index()
"""
如果函数体代码中含有多个yield关键字  执行一次__next__返回后面的值并且让代码停留在yield位置 
再次执行__next__基于上次的位置继续往后执行到下一个yield关键字处
如果没有了 再执行也会报错  StopIteration
"""
for i in res
    print(i)

自定义range方法

# range方法其实是一个可迭代对象
# 先以两个参数的range方法为例
def my_range(start, end=None, step=1):
    if not end:  # 没有给end传值  my_range(10)
        end = start
        start = 0
    while start < end:
        yield start
        start += step
for i in my_range(1,10):
    print(i)
# 初步功能实现之后 再去考虑不同参数的情况 一个参数 三个参数
# 针对一个参数情况

yield关键字作用

# 1.在函数体代码中出现 可以将函数变成生成器
# 2.在执行过程中 可以将后面的值返回出去 类似于return
# 3.还可以暂停住代码的运行
# 4.还可以接收外界的传值(了解)
def eat(name):
    print(f'{name}准备干饭')
    while True:
        food = yield
        print(f'{name}正在吃{food}')
res = eat('赵公子')
# 想执行一次代码  如果想执行多次直至结束 可以直接用for循环
res.__next__()
# res.__next__()  赵公子正在吃None
# res.__next__()  赵公子正在吃None
res.send('生日蛋糕')  # 可以给yield传值 并且自动调用一次__next__方法
res.send('大鸡腿')  # 可以给yield传值 并且自动调用一次__next__方法

生成器表达式

# 也是为了节省存储空间
	在后期我们做代码优化的时候 可以考虑使用  前期学习阶段可以忽略
 
res = (i for i in 'jason')
print(res)  # <generator object <genexpr> at 0x1130cf468>
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.read1()
"""
前提:在研究模块的时候 一定要分清楚谁是执行文件 谁是被导入文件(模块)
    模块简介.py是执行文件  md.py是被导入文件(模块)
导入模块内部到底发送了什么事情
    1.执行当前文件 产生一个当前文件的名称空间
    2.执行import句式 导入模块文件(即执行模块文件代码产生模块文件的名称空间)
    3.在当前文件的名称空间中产生一个模块的名字 指向模块的名称空间 
    4.通过该名字就可以使用到模块名称空间中的所有数据
ps:相同的模块反复被导入只会执行一次
    import md   有效
    import md   无效(写了跟没写一样)
    import md   无效(写了跟没写一样)
"""
name = 'kevin'
print(md.name)  # jNB  获取模块名称空间中的name
print(name)  # kevin  获取当前名称空间中的name
"""
import句式的特点
    可以通过import后面的模块名点的方式 使用模块中所有的名字
    并且不会与当前名称空间中的名字冲突(指名道姓)
"""

# 方式2>>>:from...import...句式
from md import name
print(name)  # jNB
name = 'kevin'
print(name)  # kevin
print(money)  # 报错  from md import name 只使用模块中的name名字
"""
1.执行当前文件产生一个名称空间
2.执行导入语句 运行模块文件产生名称空间存放运行过程中的所有名字
3.将import后面的名字直接拿到当前执行文件中
"""
"""
1.重复导入也只会导入一次
2.使用模块名称空间中的名字不需要加模块名前缀 直接使用即可
3.但是from...import的句式会产生名字冲突的问题
    在使用的时候 一定要避免名字冲突
4.使用from...import的句式 只能使用import后面出现的名字
    from...import...可以简单的翻译成中文
        从...里面拿...来用 没有提到的都不能用      指名道姓
"""

导入补充

1.可以给模块起别名(使用频率很高)
'''比如模块名或者变量名很复杂 可以起别名简写'''
import md as m
print(m.name)
from md import name as n
print(n)

2.连续导入多个模块或者变量名
import time, sys, md
from md import name, read1, read2
"""连续导入多个模块 这多个模块最好有相似的功能部分 如果没有建议分开导入
    如果是同一个模块下的多个变量名无所谓!!!
"""
import time
import sys
import md

3.通用导入
from md import *
'''*表示md里面所有的名字   from...import的句式也可以导入所有的名字
如果模块文件中使用了__all__限制可以使用的名字  那么*号就会失效 依据__all__后面列举的名字
'''
print(name)
print(money)
posted @   末笙  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示