Effective Python 读书笔记: 第17条: 在参数上面迭代时,要多加小心

本文介绍了Python中迭代器和容器的概念及其实现方式。通过自定义类实现容器,并演示了如何判断一个对象是迭代器还是容器。同时提供了示例代码来展示如何使用这些概念。
# -*- encoding: utf-8 -*-

import os

'''
第17条: 在参数上面迭代时,要多加小心

关键:
1 迭代器协议
含义:for循环遍历容器时,需要依靠迭代器写意
本质: 执行类似for x in data这样的语句时,python实际会调用iter(data)
内置的iter函数又会调用data.__iter__方法,该方法必须返回迭代器对象。
该迭代器实现了__next__方法。
fox x in data --> iter(data) --> data.__iter__ --> __next__

2 编写自己的容器
本质: 所谓容器,就是实现了自己的迭代器__iter__方法
步骤: 编写一个类,给该类实现__iter__方法,用yield返回生成器
样例:
class ReadData(object):
    def __init__(self, fileName):
        self.fileName = fileName

    def __iter__(self):
        with open(self.fileName, "rb") as fr:
            for line in fr:
                yield int(line)
                
3 总结
成为容器的方法就是编写一个类,并重写这个类的__iter__方法。
判断某个值是否时迭代器还是容器,就用值作为参数,两次调用iter函数,结果相同则为迭代器。

参考:
Effectiv Python 编写高质量Python代码的59个有效方法

'''

class ReadData(object):
    def __init__(self, fileName):
        self.fileName = fileName

    def __iter__(self):
        with open(self.fileName, "rb") as fr:
            for line in fr:
                yield int(line)


def generateFile(fileName, dataList):
    content = "\n".join(dataList)
    with open(fileName, "wb") as fr:
        fr.write(content)


def mynormalize(datas):
    # the input parameter is an iterator, raise error
    if iter(datas) is iter(datas):
        raise TypeError("Must be a container")
    total = sum(datas)
    result = []
    for value in datas:
        percent = 100.0 * value / total
        result.append(percent)
    return result


def process():
    dataList = [str(i) for i in range(4)]
    fileName = "./data.txt"
    generateFile(fileName, dataList)
    datas = ReadData(fileName)
    results = mynormalize(datas)
    print results
    datas = [0, 1, 2, 3]
    results = mynormalize(datas)
    print results
    it = iter(datas)
    results = mynormalize(it)
    print results


if __name__ == "__main__":
    process() 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值