没腿的鸟 发表于 2024-8-22 02:21:00

Python - 可迭代,迭代器,生成器,装饰器

一.可迭代对象

可迭代对象是指实现了 __iter__() 方法的对象。__iter__() 方法返回一个迭代器对象。常见的可迭代对象包摆列表、元组、字符串、字典和集合等。
s = "world"
s1 =
s2 = (1, 2, 3, 4, 5)
s3 = {"name": "猫"}
s4 = {1, 2, 3, 4, 5}
print(isinstance(s, Iterable), isinstance(s1, Iterable), isinstance(s2, Iterable), isinstance(s3, Iterable), isinstance(s4, Iterable))   
# 结果:True True True True True 分析:在这段代码中,我们使用了 isinstance() 函数来查抄差别的对象是否是可迭代对象,返回结果均为True,阐明列表、元组、字符串、字典和集合都是可迭代对象
二.迭代器

迭代器是指实现了 __iter__() 和 __next__() 方法的对象。__next__() 方法返回下一个元素,假如没有更多元素则抛出 StopIteration 异常。
类 MyDatas 的迭代器实现

class MyDatas:
    def __init__(self, n):
      """
      初始化方法,创建一个包含从1到n的整数列表,并初始化当前索引为0
      :param n: 整数,表示列表的最大值
      """
      self.datas = # 创建包含从1到n的整数列表
      self.current_index = 0# 初始化当前索引为0

    def __iter__(self):
      """
      返回迭代器对象自身
      :return: 返回self,即当前对象
      """
      return self

    def __next__(self):
      """
      返回下一个元素,如果当前索引超出列表范围,抛出IndexError异常
      :return: 返回当前元素
      """
      if self.current_index >= len(self.datas):# 检查当前索引是否超出列表范围
            raise IndexError# 抛出IndexError异常
      else:
            current = self.datas# 获取当前元素
            self.current_index += 1# 将当前索引加1
            return current# 返回当前元素

# 假设md是一个MyDatas对象,例如 md = MyDatas(5)
while True:
    try:
      for s in md:# 尝试遍历md对象
            print(s)# 打印当前元素
    except IndexError as e:# 捕获IndexError异常
      print("超出范围", e)# 打印错误信息
      break# 退出循环 分析:
__init__ 方法
初始化一个包含从1到n的整数列表 self.datas。
初始化当前索引 self.current_index 为0。
__iter__ 方法
返回迭代器对象自身,即 self。这使得 MyDatas 实例可以被用作迭代器。
__next__ 方法
查抄当前索引是否超出列表范围,假如超出则抛出 IndexError 异常。
否则,返回当前元素并将当前索引加1。
while True:
    try:
      for s in md:# 尝试遍历md对象
            print(s)# 打印当前元素
    except IndexError as e:# 捕获IndexError异常
      print("超出范围", e)# 打印错误信息
      break# 退出循环 分析:
while True 循环不断尝试遍历 md 对象。
for s in md 使用 for 循环遍历 md 对象,这会调用 md 的 __iter__() 方法获取迭代器,并调用 __next__() 方法获取下一个元素。
假如 __next__() 方法抛出 IndexError 异常,捕获该异常并打印错误信息,然退却出循环。
总结:
迭代器:实现了 __iter__() 和 __next__() 方法的对象。
自定义迭代器:通过定义类并实现 __iter__() 和 __next__() 方法来创建自定义迭代器。
迭代器的使用:通过 for 循环或其他迭代方式使用迭代器,自动调用 __iter__() 和 __next__() 方法。
异常处理:在迭代过程中处理可能抛出的异常(如 IndexError)。
三.生成器

生成器是Python中一种特殊的迭代器,它使用 yield 关键字来产生值。生成器函数在调用时返回一个生成器对象,每次调用 next() 时,生成器函数会从前次 yield 的位置继续执行,直到遇到下一个 yield 或函数竣事。
生成器的基本概念

生成器函数使用 yield 关键字来产生值,而不是 return。每次调用 next() 时,生成器函数会从前次 yield 的位置继续执行,直到遇到下一个 yield 或函数竣事。
生成器函数

def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
for item in gen:
    print(item) 分析:在这个例子中,my_generator 是一个生成器函数,它使用 yield 关键字来产生值。调用 my_generator() 返回一个生成器对象 gen,我们可以使用 for 循环来遍历它。
生成器表达式

gen = (x for x in range(1, 4))
for item in gen:
    print(item) 分析:(x for x in range(1, 4)) 是一个生成器表达式,它返回一个生成器对象 gen,我们可以使用 for 循环来遍历它。
上风

结合 sys.getsizeof() 函数,我们可以更直观地理解生成器在内存使用上的上风。sys.getsizeof() 函数用于获取对象的内存占用大小(以字节为单元)。
# 创建一个包含100万个整数的列表
list_data =

# 创建一个生成器表达式,生成100万个整数
gen_data = (i for i in range(1000000))

# 打印列表和生成器的内存占用大小
print(list_data.__sizeof__())
print(gen_data.__sizeof__())

# 结果:8448712176
分析:通过比较列表和生成器的内存占用大小,我们可以直观地看到生成器在处理大数据集时的内存上风。生成器非常适合处理大数据集,因为它不会一次性将全部数据加载到内存中,从而节省内存资源。
四.装饰器

装饰器是一种用于修改函数或方法行为的高阶函数。装饰器本质上是一个返回函数的函数,它可以在不修改原函数代码的情况下,增加额外的功能。
# 装饰器
def cost_time(f):
    def calc():
      start = time.time()
      f()
      print(f"{f.__name__}的时间开销是{time.time() - start}")

    return calc


data =
datas = data.copy()


@cost_time
def my_sort1():
    data.sort()
    print(data)


# my_sort1 = cost_time(my_sort1)
my_sort1()


@cost_time
def my_sort2():
    new_datas = sorted(datas, reverse=False)
    print(new_datas)


# my_sort2 = cost_time(my_sort2)
my_sort2()
装饰器 cost_time

def cost_time(f):
    def calc():
      start = time.time()
      f()
      print(f"{f.__name__}的时间开销是{time.time() - start}")

    return calc cost_time 是一个装饰器函数,它接受一个函数 f 作为参数。
在 cost_time 内部定义了一个嵌套函数 calc,这个函数用于测量 f 的执行时间。
start = time.time():纪录函数开始执行的时间。
f():调用原函数 f。
print(f"{f.__name__}的时间开销是{time.time() - start}"):打印函数 f 的名称和执行时间。
cost_time 返回嵌套函数 calc,如许当装饰器应用到一个函数时,实际上是返回了一个新的函数 calc,这个函数包含了原函数 f 的调用和时间测量逻辑
函数 my_sort1 和 my_sort2

@cost_time
def my_sort1():
    data.sort()
    print(data)

# my_sort1 = cost_time(my_sort1)
my_sort1()

@cost_time
def my_sort2():
    new_datas = sorted(datas, reverse=False)
    print(new_datas)

# my_sort2 = cost_time(my_sort2)
my_sort2() my_sort1 和 my_sort2 是两个用于排序的函数。
@cost_time 语法是装饰器的应用,相当于 my_sort1 = cost_time(my_sort1) 和 my_sort2 = cost_time(my_sort2)。
这表示在调用 my_sort1 和 my_sort2 时,实际上是调用了 cost_time 返回的 calc 函数。
my_sort1 使用 list.sort() 方法对 data 进行原地排序。
my_sort2 使用 sorted() 函数对 datas 进行排序,并返回一个新的排序后的列表 new_datas。
总结
装饰器 cost_time 用于测量函数执行的时间开销。
my_sort1 和 my_sort2 分别使用差别的排序方法对数据进行排序。
通过装饰器,我们可以在不修改原函数代码的情况下,增加时间测量的功能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Python - 可迭代,迭代器,生成器,装饰器