Python入门十二天- 迭代器、生成器和模块

本文介绍了Python中的有参装饰器、迭代器和生成器的概念及应用,详细讲解了如何创建和使用生成器,并探讨了模块的导入与使用方法,包括import、from...import等不同导入方式的细节。
摘要由CSDN通过智能技术生成

day12 - 迭代器、生成器和模块

一、有参装饰器

1、应用场景

  • 如果实现装饰器的功能时需要额外的数据,就需要有参装饰器

2、固定语法

  • def 函数名(参数列表):

​ 定义无参装饰器函数

​ return 午餐装饰器函数名

  • 参数列表 - 参数列表的个数是看实现装饰器功能时需要多少个额外的数据,如果不需要额外的数据就使用无参装饰器
  • 函数名 - 创建装饰器的函数名
def creat_tag(name):
    def tag(f):
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)
            return f'<{name}>{result}</{name}>'
        return new_f
    return tag


@creat_tag('a')
def func1():
    return 'hello'

print(func1())         # <a>hello</a>
# 练习:写个装饰器将原函数的返回值加上指定的数
def add_number(num):
    def number(f):
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)
            if type(result) in (int, float, bool, complex):
                return result + num
            return result
        return new_f
    return number
@add_number(10)
def func2(a):
    return a*2
print(func2(10))       # 30

二、迭代器

1、什么是迭代器(iter)

  • 迭代器是容器型数据类型
  • 迭代器无法直接获取所有的元素,只能一个一个的取,也无法通过len统计元素的个数
  • 迭代器的查或者取操作是一个一个的从容器里拿出来,而且支出不进
  • 创建迭代器的方法:a.将其他序列转换成迭代器 - iter()b.生成器
list1 = [1, 20, 4, 56]
i1 = iter(list1)
print(i1)        # <list_iterator object at 0x000001DE3B1308C8>
print(i1, type(i1))   # <list_iterator object at 0x000001FDCD2B08C8> <class 'list_iterator'>
# print(len(i1))   # 迭代器无法通过len统计元素的个数

2、获取元素(查)

  • 不管以什么样的方式得到了迭代器中的元素,迭代器里面就不再存在该元素
(1)获取单个元素
  • next (迭代器)
(2)遍历
  • for 变量 in 迭代器

​ 循环体

  • 遍历迭代器遍历结束,迭代器也就空了
i2 = iter('hello')
print(next(i2))      # h
# i3遍历结束的时候会变成空的迭代器
i3 = iter(range(5))
for x in i3:
    print(f'x:{x}')
'''
x:0
x:1
x:2
x:3
x:4
'''
print(list(i3))       # [],i3变成了空的迭代器,转换成列表就是空列表

i4 = iter(range(0, 10, 2))
# i4转换成列表之后会变成空的迭代器
print(list(i4))    # [0, 2, 4, 6, 8]
# print(next(i4))    # 迭代器里面已经空了,会报错 StopIteration

三、生成器

1、什么是生成器

(1)感性认识
  • 生成器是一种特殊的迭代器
  • 生成器可以理解成生产数据的机器,在存储时其实保存的是产生数据的算法,而不是数据本身
(2)理性认识
  • 调用带有yield关键字的函数就可以得到一个生成器
  • 如果一个函数中有yield,那么调用这个函数不会执行函数体,也不会获取返回值,函数调用表达式的值是一个生成对象
def func1():
    print('========')
    return 100

result = func1()
print(f'result:{result}')
# ========
# result:100

2、怎么创建生成器

def func2():
    yield
    print('========')
    return 100

result = func2()    # result就是一个生成器
print(f'result:{result}')  # result:<generator object func2 at 0x0000010621C3AB48>

3、生成器产生数据的能力怎么确定

  • 看执行完生成器对应的函数会遇到几次yield,那么这个生成器就可以创造多少个数据
  • 每次遇到yield,yield后面的值是什么,对应创造的数据就是什么
def func3():
    yield
    yield 10
    yield 100
gen1 = func3()
print(next(gen1))    # None
print(next(gen1))    # 10
print(next(gen1))    # 100

def func4():
    for x in range(5):
        yield 10**2

gen2 = func4()
for x in gen2:
    print(f'x:{x}')

3、产生数据的原理

  • 生成器对应的函数在调用函数的时候不会执行函数体;获取生成器中的数据的时候才会执行函数体,每次获取数据的时候都是从上一次结束的位置开始执行函数体,直到遇到yield就停下来,将yield后面的数据作为结果返回并记录结束位置
  • 如果是next去取, 执行的时候如果遇到函数结束都没遇到yield就报错
def func4():
    print('==============1========')
    yield 10
    print('========2======')
    yield 20
    yield 30
    yield 40
gen3 = func4()
print('第一次取:', next(gen3))
# ==============1========
# 第一次取: 10
print('第二次取:', next(gen3))
# ========2======
# 第二次取: 20
# 练习:写一个生成器能够产生指定前缀指定长度的学号
# 1 -> 001; 23 -> 023
def add_prefix_length(prefix, length):
    for x in range(1, 10**length):
        result = prefix + str(x).zfill(length)
        yield result

nums = add_prefix_length('py', 3)
print(nums)         # <generator object add_prefix_length at 0x000001C9F51EAD48>
print(next(nums))     # py001
for _ in range(10):
    print(next(nums))
print('==:', next(nums))

四、模块

1、什么是模块

  • python中一个py文件就是一个模块

2、怎么在一个模块中使用另外一个模块的内容

  • 注意:一个模块要是想要被其他模块使用,那么这个模块在命名的时候必须符合标识符的要求
  • 一个模块要想使用另外一个模块中的内容,必须先导入
(1)import 模块名
  • 导入指定模块,能够使用模块中的所有全局变量
  • 使用时通过‘模块名.'的方式
# 1)第一种导入方式:import
import test
print(test.test_a)       # 100
(2)from 模块名 import 变量名1,变量名2…
  • 能够使用模块中的指定变量
  • 使用时变量直接使用,没有导入的不能使用
# 2)第二种导入方式
from test import test_a
print(test_a)             # 100
(3)模块重命名:import 模块 as 新模块名
# 3)第三种导入方式:模块重命名
import test as TS
print(TS.test_a)         # 100
(4)变量重命名:from 模块名 import 变量 as 新变量名
  • 要对哪个变量重命名就在哪个变量后面加as,不需要重命名的就保持原来的样子
# 4)第四种导入方式:变量重命名
from test import test_a as new_a
print(new_a)
(5)导入所有变量:from 模块 import*

五、导入模块的原理

  • 当代码执行到导入模块的时候,系统会自动将被导入的模块中的代码全部执行一遍
  • 放在if语句里面的代码在被别的代码导入的时候就不会执行,if语句外面的就会执行
  • 如果直接运行当前模块,模块这个if中的代码会被执行
if __name__ == '__main__':
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值