你真的了解内置函数iter吗?

python中有一个内置的函数iter,相信所有都知道它的用法,就是传入一个可迭代对象得到一个迭代器。

lst = [1, 2, 3]

print(iter(lst))  # <list_iterator object at 0x00000217100D4E50>
print(iter(lst).__next__())  # 1

但这只是iter的第一个用法,你知道它的第二个用法吗?iter还可以接收一个可调用对象和一个value,iter(callable, value),然后会不断地调用callable,直到返回的值等于value的时候终止迭代。我们举例说明:

i = iter(str, "abc")
print(i)  # <callable_iterator object at 0x0000027447BA4E50>
# 直接打印是一个迭代器,但如果使用for循环对i进行遍历的话会得到什么结果呢?
# 答案是会无限循环,我们说会不断地调用callable,直到返回的值等于value
# 而调用str返回的是一个空字符串,而空字符串不等于"abc", 因此会一直调用
for idx, _ in enumerate(i):
    if idx > 4:
        break
    print("%r" % _)
    """
    ''
    ''
    ''
    ''
    ''
    """
# 我们当前只打印5次,如果是for _ in i:的话,那么会无限循环


lst = [11, 22, 33, 44, 55]
for _ in iter(iter(lst).__next__, 44):
    print(_)
"""
11
22
33
"""


# 再比如
def foo():
    yield "a"
    yield "b"
    yield "c"
    yield "d"


for _ in iter(foo().__next__, "c"):
    print(_)
    """
    a 
    b 
    """

需要注意的是:对于iter(foo().__next__, "c")来说,相当于f = foo();iter(f.__next__, "c"),并不是每次都重新执行一次foo(),这一点需要注意。同理,对于iter(iter(lst).__next__, 44)也是如此。

这种方式可以用在socket通信中,当然文件的读取也可以,只不过文件读取的话没必要使用这种方式,不过就用文件读取来演示一下吧

from functools import partial

data = b""
f = open("1.txt", "rb")

# 每次读取3个字节
reader = partial(f.read, 3)

# 不停地调用reader,直到内容读取完毕,再次读取返回空字节的时候,结束循环
for _ in iter(reader, b""):
    data += _

print(data.decode("utf-8"))  # 那一日,人们终于回想起被巨人支配的恐惧
posted @ 2019-08-09 13:59  古明地盆  阅读(566)  评论(0编辑  收藏  举报