再谈迭代器,生成器,yield,及和类的使用

最近写项目时,遇到类嵌套和yield的混合使用,觉得比较典型,正好借此加深对迭代器和生成器的理解。

代码

代码抽象如下:

from types import FunctionType


class RowItems(object):
    def __init__(self,option,x1,x2,x3):
        self.option = option
        self.x1 = x1
        self.x2 = x2
        self.x3 = x3


    def __iter__(self):
        yield 1
        yield 11
        yield 111
        yield 1111
        yield 11111
        yield 111111
        yield 1111111


class Option(object):
    def __init__(self,name_or_func,status):
        self.name_or_func = name_or_func
        self.status = status

    def is_func(self):
        if isinstance(self.name_or_func,FunctionType):
            return True


def func(configs):
    for option in configs:
        if option.is_func():
            data_list = None
        else:
            data_list = RowItems(option,11,22,33)

        yield data_list


list_filter_config = [
    Option('name',True),
    Option('email',True),
]

result = func(list_filter_config)
for v in result:

    for j in v:
        print(j)

打印结果如下:

1
11
111
1111
11111
111111
1111111
1
11
111
1111
11111
111111
1111111


知识准备:

关于迭代器和生成器的基本知识,可以参考 http://blog.csdn.net/ayhan_huang/article/details/73374894

我们知道,可迭代对象都具有__iter__方法,因此只要在类中定义该方法,那么其实例化对象就是可迭代对象,就可以被for循环,比如:

class Foo(object):
    def __iter__(self):
        return iter([1,2,3])

obj = Foo()
for i in obj:
    print(i)

""" 打印结果
1
2
3
"""


而如果一个函数中有yield,那么执行函数就会拿到一个生成器(生成器就是迭代器)。

流程分析:

下面我们具体看一下本文开头给出的那段代码的执行流程

  1. list_filter_config 中拿到两个实例化对象,假设为: A & B
  2. result = func(list_filter_config),未执行func具逻辑,直接拿到一个生成器对象,假设为F_gen
  3. for v in result: 执行生成器,F_gen
  4. 执行func :
    1. 循环list_filter_config第一个元素 A
    2. 实例化RowItems对象,得到可迭代对象,假设为:A_iter
    3. func:yield A_iter 返回 A_iter
  5. 回到for v in result: A_iter, F_gen
    1. for j in v: 迭代A_iter:每打印一行,回到for j in v,触发A_iter继续迭代
    2. 迭代A_iter 完成,打印出第一个金字塔
  6. 回到for v in result: F_gen
  7. 执行func :
    1. 循环list_filter_config第二个元素 B
    2. 实例化RowItems对象,得到可迭代对象,假设为:B_iter
    3. func:yield B_iter 返回 B_iter
  8. 回到for v in result: B_iter
    1. for j in v: 迭代B_iter:每打印一行,回到for j in v,触发B_iter继续迭代
    2. 迭代B_iter完成,打印出第二个金字塔
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值