国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

4.6 帶有外部狀態(tài)的生成器函數(shù)

2018-02-24 15:26 更新

問題

你想定義一個生成器函數(shù),但是它會調用某個你想暴露給用戶使用的外部狀態(tài)值。

解決方案

如果你想讓你的生成器暴露外部狀態(tài)給用戶,別忘了你可以簡單的將它實現(xiàn)為一個類,然后把生成器函數(shù)放到iter()方法中過去。比如:

from collections import deque

class linehistory:
    def __init__(self, lines, histlen=3):
        self.lines = lines
        self.history = deque(maxlen=histlen)

    def __iter__(self):
        for lineno, line in enumerate(self.lines, 1):
            self.history.append((lineno, line))
            yield line

    def clear(self):
        self.history.clear()

為了使用這個類,你可以將它當做是一個普通的生成器函數(shù)。然而,由于可以創(chuàng)建一個實例對象,于是你可以訪問內部屬性值,比如 history 屬性或者是 clear() 方法。代碼示例如下:

with open('somefile.txt') as f:
    lines = linehistory(f)
    for line in lines:
        if 'python' in line:
            for lineno, hline in lines.history:
                print('{}:{}'.format(lineno, hline), end='')

討論

關于生成器,很容易掉進函數(shù)無所不能的陷阱。如果生成器函數(shù)需要跟你的程序其他部分打交道的話(比如暴露屬性值,允許通過方法調用來控制等等),可能會導致你的代碼異常的復雜。如果是這種情況的話,可以考慮使用上面介紹的定義類的方式。在 __iter__() 方法中定義你的生成器不會改變你任何的算法邏輯。由于它是類的一部分,所以允許你定義各種屬性和方法來供用戶使用。

一個需要注意的小地方是,如果你在迭代操作時不使用for循環(huán)語句,那么你得先調用 iter() 函數(shù)。比如:

>>> f = open('somefile.txt')
>>> lines = linehistory(f)
>>> next(lines)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: 'linehistory' object is not an iterator

>>> # Call iter() first, then start iterating
>>> it = iter(lines)
>>> next(it)
'hello world\n'
>>> next(it)
'this is a test\n'
>>>
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號