生成器与模块

生成器对象

# 本质还是迭代器 只不过是通过我们自己写代码而生成
	也有__iter__方法和__next__方法
def index():
    print('hello')
    yield 123
    print('jason')
    yield
# 生成器对象也是节省存储空间的,特性与迭代器对象一致
'''
当函数体代码中含有yield关键字的时候,第一次调用并不会执行函数体代码,而是将函数变成生成器
'''
print(index)  # <function index at 0x000002B564DF1F28>  不进行调用就是普通的函数

print(index())  # <generator object index at 0x000002B5654C0A98> 调用后就会变成生成器
# 当函数变成生成器之后,可以通过调用__next__()来执行函数体代码
# 先调用函数
res = index()
next(res)  # 'hello'
next(res)  # 'jason'
next(res)  # 报错

'''当函数体代码中含有多个yield关键字的时候 执行一次__next__()yield上面的代码就会被执行,并停留在yield
再次执行__next__()就会基于上此停止的位置继续往后执行到下一个yield,如果下面没有yield就会报错'''
 

自定义range方法

# range方法是一个可迭代对象
通过生成器模拟range方法
def my_range(start,end=False,step=1):
    if not end:
        end = start
        start = 0
    while start < end:
        yield start
        start += step

for i in my_range(5):
    print(i)

yield关键字的作用

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

def eat(name):
    print('hello')
    while True:
        name = yield
        print(name)

res = eat('jason')
next(res)  # hello
next(res)  # None
res.send('drink')  # drink  send可以给yield传值,并自动调用一次__next__


生成器表达式

# 也是为例节省存储空间
	后期进行代码的优化的时候可以考虑使用
res = (i for in 'jason')
# res 就是生成器对象
'''生成器内部的代码只有在调用__next__迭代取值的时候才会执行'''

#题目实战
def add(n, i):
    return n + 1

def test():
    for i in range(4):
        yield i 

g = test()

for n in [1, 10]
	g = (add(n, i) for i in g)
res = list(g)
print(res)
res = [20,21,22,23]

模块

'''
很多大佬写了很多很厉害的模块 供python工程师直接使用,因此当我们遇到一个非常复杂的功能需要实现的时候,第一时间相对应该是取网上能不能找到想应的模块
'''
# 什么是模块
	模块就是一系列功能的结合体,可以直接使用
# 为什么要用模块
	极大的提升开发的效率
# 模块的三种来源
	1.内置的模块
    无需下载 解释器自带 直接导入即可
    2.自定义模块
    自己写的代码封装成模块自己使用或者发布到网上供别人使用
    3.第三方模块
    别人写的发布到网上的 可以下载使用的模块
    # 模块的四种表现形式
    1.使用python代码编写py文件
    2.多个py文件组成的文件夹
    3.已被编译为共享库或DLL的C或C++扩展
    4.使用c编写并链接到python解释器的内置模块

模块的两种导入方式

# 使用模块前,必须先进行导入,而导入的方法有两种
# 方式1>>>:import 包名
比如导入time模块
import time
'''
一定要分清谁是执行文件,谁是导入文件(模块)
导入模块内部发生了什么
1.执行当前文件 产生一个当前文件的名称空间
2.执行import句式 导入模块文件(即执行模块文件代码模块文件的名称空间)
3.在当前文件的名称空间中生成一个模块的名字,指向模块的名称空间
4.通过在执行文件中生成的名字可以使用模块名称空间中的所有数据
'''
# import句式的特点
    1.相同模块重复导入只会被执行一次
    2.可以通过import后面的模块点名的方式,使用模块中所有的名字
    3.模块当中的名字不会和执行文件中的名字冲突
    
# 方式2:from 模块名 import 方法名
from time import time,tzset
'''
1.执行当前文件产生一个名称空间
2.执行导入语句 运行模块文件产生名称空间,存放运行中产生的所有名字
3.将import后面的名字直接拿到执行问价中
'''
# 该方式的特点
1.重复导入只会执行一次
2.使用模块名称空间中的名字不需要加模块名前缀,直接使用即可
3.导入的名称会与执行文件中的名称产生冲突。因为他是直接将模块中的方法存放到执行文件的名称空间
4.使用from...import...的句式,只能使用import中出现的名字

导入补充

# 1.可以给模块起别名,比如当模块名称非常复杂的时候可以用简单的别名代替
import time as t
就是将time模块的名称替换成t   调用方法的时候直接t.就行

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

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