python 可迭代,迭代器,生成器,装饰器

1. 可迭代(Iterable)

可迭代 是指一个对象可以返回一个迭代器的对象。也就是说,它实现了 __iter__() 方法或 __getitem__() 方法。常见的可迭代对象有列表、元组、字符串、字典和集合。

from collections.abc import Iterable

i = 100
s = "hello"
l = [1, 2, 3]
t = (1, 2, 3)
d = {"name": "qiku"}
set0 = {1, 2, 3}

print(
    isinstance(i, Iterable),  # False, 整数不可迭代
    isinstance(s, Iterable),  # True, 字符串可迭代
    isinstance(l, Iterable),  # True, 列表可迭代
    isinstance(t, Iterable),  # True, 元组可迭代
    isinstance(d, Iterable),  # True, 字典可迭代(迭代的是键)
    isinstance(set0, Iterable) # True, 集合可迭代
)

2. 迭代器(Iterator)

迭代器 是一个对象,它实现了 __iter__()__next__() 方法(在 Python 3 中,__next__() 方法被称为 __next__())。迭代器可以用于遍历序列中的元素,每次调用 __next__() 方法时,它返回序列中的下一个元素。迭代器在遍历完所有元素后会抛出 StopIteration 异常。

from collections.abc import Iterable, Iterator  # 从 collections.abc 模块导入 Iterable 和 Iterator

class MyDatas:
    def __init__(self, n):
        # 初始化数据列表,从 1 到 n
        self.datas = [i for i in range(1, n + 1)]
        self.current_index = 0  # 当前索引,初始化为 0

    def __iter__(self):
        # 返回自身,因为它既是可迭代对象也是迭代器
        return self

    def __next__(self):
        # 如果当前索引超出数据列表的长度,抛出 StopIteration 异常,表示迭代结束
        if self.current_index >= len(self.datas):
            raise StopIteration
        else:
            # 返回当前索引的数据,并将当前索引加 1
            current = self.datas[self.current_index]
            self.current_index += 1
            return current

md = MyDatas(5)  # 创建一个包含 1 到 5 的 MyDatas 实例

# 打印 md 是否是 Iterable 和 Iterator
print(isinstance(md, Iterable), isinstance(md, Iterator))

# 遍历 MyDatas 实例中的所有数据
for d in md:
    print(d)

3. 生成器(Generator)

生成器 是一种特殊类型的迭代器,使用函数和 yield 关键字来创建。生成器函数可以像普通函数一样定义,但它们使用 yield 来返回值,而不是 return。每次调用生成器的 __next__() 方法时,它会从上次 yield 语句处继续执行,直到遇到下一个 yield 语句或函数结束。

# 定义一个列表 l0,并打印其内存大小
l0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print(l0.__sizeof__())  # 打印 l0 列表在内存中占用的字节数
print(l0[15])  # 打印列表中索引为 15 的元素

# 定义一个生成器表达式 t0,并打印其内存大小
t0 = (i for i in range(1, 1000000000))
print(t0.__sizeof__())  # 打印生成器 t0 在内存中占用的字节数
print(isinstance(t0, Iterable), isinstance(t0, Iterator), isinstance(t0, Generator))  
# 打印 t0 是否是 Iterable、Iterator 和 Generator 类型
print(next(t0), next(t0))  # 打印生成器 t0 的前两个值

# 定义一个生成器函数 my_datas
def my_datas():
    yield 1
    yield 2
    yield 3
    yield 10
    yield 20
    yield 30
    return 100  # 生成器结束时返回的值

r = my_datas()  # 创建生成器对象 r

print(type(r))  # 打印生成器对象 r 的类型

# 使用 while 循环遍历生成器 r 的所有值
while True:
    try:
        print(next(r))  # 打印生成器 r 的下一个值
    except StopIteration as e:  # 捕捉 StopIteration 异常,表示生成器已结束
        print("取完了", e)  # 打印生成器结束时返回的值
        break  # 退出循环

生成器在内存中占用的字节数通常是固定的,比如在上述例子中是 184 字节。即使列表的元素数量增加,生成器的内存占用也不会显著增加。相比之下,当列表中的元素数量增加时,其内存占用量会显著增长。这是因为列表需要为每个元素分配额外的内存来存储数据。而生成器只在需要时生成数据,因而在处理大量数据时,生成器通常比列表更加节省内存。

4. 装饰器(Decorator)不改变函数原有实现给函数添加新功能

装饰器 是一种用于修改或扩展函数或方法行为的设计模式。装饰器是一个函数,它接受一个函数作为参数,并返回一个新的函数。它们常用于日志记录、权限检查、缓存等。

import time
import random

# 定义一个装饰器函数 cost_time,用于计算函数执行时间
def cost_time(f):
    # 定义内部函数 calc,计算并打印被装饰函数的执行时间
    def calc():
        start = time.time()  # 记录开始时间
        f()  # 调用被装饰的函数
        print(f"函数{f.__name__}开销:{time.time() - start}")  # 计算并打印执行时间

    return calc  # 返回内部函数 calc

# 生成一个包含 10000 个随机整数的列表 datas
datas = [random.randint(0, 10000) for i in range(10000)]
# 创建 datas 的副本 datas2
datas2 = datas.copy()

# 使用 cost_time 装饰器装饰 my_sort1 函数
@cost_time
def my_sort1():
    datas.sort(reverse=True)  # 对列表 datas 进行降序排序
    print(datas)  # 打印排序后的列表

# 使用 cost_time 装饰器装饰 my_sort2 函数
@cost_time
def my_sort2():
    datas3 = sorted(datas2, reverse=True)  # 对列表 datas2 进行降序排序,并生成新列表 datas3
    print(datas3)  # 打印排序后的新列表

# 调用装饰后的 my_sort1 函数,计算其执行时间并打印排序结果
my_sort1()

# 调用装饰后的 my_sort2 函数,计算其执行时间并打印排序结果
my_sort2()

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的迭代器生成器装饰器都是非常重要的编程概念,下面分别介绍一下: 1. 迭代器 Python中的迭代器是一种可以遍历集合中元素的对象,可以使用for循环遍历集合中的元素。迭代器实现了两个方法:__iter__()和__next__()。__iter__()方法返回迭代器对象自身,__next__()方法返回集合中的下一个元素。 下面是一个简单的使用迭代器遍历列表的示例: ``` my_list = [1, 2, 3] my_iterator = iter(my_list) for i in my_iterator: print(i) ``` 2. 生成器 生成器是一种特殊的函数,可以在执行过程中多次返回值,而不是只返回一次。生成器使用yield语句返回值,可以暂停函数的执行,并在需要时继续执行。 下面是一个简单的生成器示例: ``` def my_generator(): yield 1 yield 2 yield 3 for i in my_generator(): print(i) ``` 3. 装饰器 装饰器是一种可以修改函数或类的行为的函数,可以在不修改原始代码的情况下添加额外的功能。装饰器本质上是一个可以接受函数或类作为参数的函数,可以在不修改原始函数或类的情况下修改其行为。 下面是一个简单的装饰器示例: ``` def my_decorator(func): def wrapper(): print("Before the function is called.") func() print("After the function is called.") return wrapper @my_decorator def my_function(): print("Inside the function.") my_function() ``` 在上面的代码中,我们定义了一个装饰器函数my_decorator,它接受一个函数作为参数,并返回一个新的函数wrapper。这个新函数在调用原始函数之前和之后打印一些文本。我们使用@符号将装饰器应用到my_function函数上,这样my_function函数的行为就被修改了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值