我试图了解如何使用“收益率”。为此,我编写了一个简单的(相当没用) 示例(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
我一直在尝试和研究文档。下面(IMHO)是我认为正确的代码。我从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)
我一直在研究PEP380。我不能说我在上面找到了对上述代码的确认。