我试图了解如何使用“收益”。为此,我编写了一个简单(相当无用)的示例(count_vowels.py),运行时会在下面生成:
$ python3 count_vowels.py
Counter({'a': 5})
请解释为什么 proxy2 函数(委托生成器)中需要“while True”?
没有'while True':
$ python3 count_vowels.py
Traceback (most recent call last):
File "count_vowels.py", line 39, in <module>
main()
File "count_vowels.py", line 34, in main
p.send(None)
StopIteration
我不明白为什么需要'while True'。我知道没有其他方法可以修改示例以使其工作。
count_vowels.py
from collections import Counter
VOWELS = 'AEIOU'
def counter2():
cnt2 = Counter()
while True:
c = yield
if c is None:
break
if str.upper(c) in VOWELS:
cnt2[c] += 1
return cnt2
def proxy2(cnt):
while True: # w/o this while I get 'StopIteration' exception
tmp = yield from counter2()
cnt.update(tmp)
def main():
word = 'abracadabra'
cnt = Counter()
p = proxy2(cnt)
next(p)
for c in word:
p.send(c)
p.send(None)
print(cnt)
if __name__ == '__main__':
main()
使用 Python3.5.3,Debian GNU/Linux 9.8(拉伸)
更新:Windows7,Python 3.7.2,同样的结果。
更新:05/04 p.send(None) 在 proxy2 中没有“while True”会引发 StopIteration。我修改了proxy2:
def proxy2(cnt):
tmp = yield from counter2()
cnt.update(tmp)
yield
同样,我没有看到任何解释,但它有效。
更新 04/05
我一直在试验和研究文档。下面(恕我直言)是我看起来正确的代码。我从 proxy2 中删除了多余的“收益”。
def counter2(cnt):
while True:
c = yield
if c is None:
break
if isinstance(c, (str)) and (str.upper(c) in VOWELS):
cnt[c] += 1
return cnt
def proxy2(cnt):
tmp = yield from counter2(cnt)
return tmp
def main():
word = 'abracadabra'
cnt = Counter()
p = proxy2(cnt)
next(p)
for c in word:
p.send(c)
try:
p.send(None)
except StopIteration as exc:
res = exc.value
print(res)
我一直在研究 PEP 380。我不能说我在那里找到了上面代码的确认。