pythonジェネレータとコモンシップ
4056 ワード
yield
pythonジェネレータのyieldの場合、yield itemはnext()の呼び出し元に値を生成し、next()を呼び出すまでジェネレータを停止します.
きょうてい
コパスでは、yieldは通常、式の右側(data=yield)に表示され、値を返すことも、返さないこともできます(yieldの後ろに式がない場合はNoneを返します).ジェネレータの呼び出し元はsend()メソッドを使用してデータを送信でき、送信されたデータはyield式の値になります.したがって、ジェネレータは、コヒーレントとして使用することができる.
コラボレーションは、呼び出し元と協力して呼び出し元から提供される値を生成するプロセスです.
***f.send()を使用する前に、必ずプレアクティブ***
コンポジットの使い方を簡略化するために、プレエキサイティングアクセサリーを使用することができます.
コンシステントおよび例外処理の終了
コンシステント内に例外が処理されていない場合、コンシステントは終了し、コンシステントが再び呼び出され、StopIteration例外が放出されます.
コンシステントを値に戻す
コンシステントでreturnを使用して返される値は、StopIteration例外のvalue変数に配置され、この例外をキャプチャして取得できます.
yield from
yield fromを使用すると、StopIteration例外が自動的にキャプチャされ、value変数の値がyield from式の値になります.
yield fromは呼び出し方法を内層のサブジェネレータに接続する、外層の呼び出し方法は内層のジェネレータに直接値を伝達することができ、サブジェネレータが返す値はyield fromによって受信する.例を見てみましょう
pythonジェネレータのyieldの場合、yield itemはnext()の呼び出し元に値を生成し、next()を呼び出すまでジェネレータを停止します.
def func():
for i in range(10):
yield i
f = func()
next(f)
きょうてい
コパスでは、yieldは通常、式の右側(data=yield)に表示され、値を返すことも、返さないこともできます(yieldの後ろに式がない場合はNoneを返します).ジェネレータの呼び出し元はsend()メソッドを使用してデータを送信でき、送信されたデータはyield式の値になります.したがって、ジェネレータは、コヒーレントとして使用することができる.
コラボレーションは、呼び出し元と協力して呼び出し元から提供される値を生成するプロセスです.
>>> def func():
... for i in range(10):
... r = yield i # yield , i
... print(r)
...
>>> f = func()
>>> next(f) #
0
>>> f.send(10)
10
1
***f.send()を使用する前に、必ずプレアクティブ***
コンポジットの使い方を簡略化するために、プレエキサイティングアクセサリーを使用することができます.
import functools
def wrapper(func):
@functools.wraps(func) # wraps func
def inner(*args, **kwargs):
gen = func(*args, **kwargs)
next(gen)
return gen
return inner
def func():
for i in range(10):
r = yield i
print(r)
コンシステントおよび例外処理の終了
コンシステント内に例外が処理されていない場合、コンシステントは終了し、コンシステントが再び呼び出され、StopIteration例外が放出されます.
>>> f = func()
>>> f.send(10)
100
1
>>> f.send('hello')
Traceback (most recent call last):
File "", line 1, in
File "", line 5, in func
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
>>> f.send(10)
Traceback (most recent call last):
File "", line 1, in
StopIteration
コンシステントを値に戻す
コンシステントでreturnを使用して返される値は、StopIteration例外のvalue変数に配置され、この例外をキャプチャして取得できます.
yield from
yield fromを使用すると、StopIteration例外が自動的にキャプチャされ、value変数の値がyield from式の値になります.
def func():
for i in range(10):
r = yield i
yield from rang(10) func()
yield fromは呼び出し方法を内層のサブジェネレータに接続する、外層の呼び出し方法は内層のジェネレータに直接値を伝達することができ、サブジェネレータが返す値はyield fromによって受信する.例を見てみましょう
#!/usr/bin/env python3
from collections import namedtuple
Result = namedtuple('Result', 'count average')#
# averager ,
def averager():
total = 0.0
count = 0
average = None
while True: # main
term = yield
if term is None: #
break
total += term
count += 1
average = total/count
return Result(count, average) # Result grouper yield from
#
def grouper(results, key):
# averager ,
while True: # grouper yield from , averager 。grouper yield from , averager 。averager , results[key] 。while averager , 。
results[key] = yield from averager()
#
def main(data):
results = {}
for key, values in data.items():
# group grouper , grouper results, ;
group = grouper(results, key)
next(group)
for value in values: # value grouper averager ;
# grouper , grouper yield from
group.send(value) # None groupper, averager , 。 。
# group.send(None), averager , , result[key]
group.send(None)
report(results)
#
def report(results):
for key, result in sorted(results.items()):
group, unit = key.split(';')
print('{:2} {:5} averaging {:.2f}{}'.format(result.count, group, result.average, unit))
data = {
'girls;kg':[40, 41, 42, 43, 44, 54],
'girls;m': [1.5, 1.6, 1.8, 1.5, 1.45, 1.6],
'boys;kg':[50, 51, 62, 53, 54, 54],
'boys;m': [1.6, 1.8, 1.8, 1.7, 1.55, 1.6],
}
if __name__ == '__main__':
main(data)