0

関数インスタンス自体だけでなく、ジェネレーター関数をインスタンス化する呼び出し元により多くの情報を返すことができる方法はありますか?

例えば、

def genFn(a, b, c):
    # some initialisation / pre-computation
    startPt = fn(a, b, c)
    data = (yield None)
    while True:
        # perform some computation
        data = (yield result)

f = genFn(5, 6, 7)
start = f.get("startPt") # this line syntax is wrong - just to show what I want
f.send(None)
for data in dataseries[startPt:]:
    k = f.send(data)
    ...

渡されたパラメーター(a、b、c)に基づいて、関数には、必要な最も早いデータを計算するロジックがあります。どういうわけか、この情報を「必要な最も古いデータ」から発信者に返すことができるようにしたいと思います。私は確かに呼び出し元に同じ情報を計算して到達させることができますが、それは労力の重複であり、ジェネレーター関数の複雑さをカプセル化したいのでエレガントではありません。

ありがとう

T

4

2 に答える 2

1

send最初の呼び出しの現在使用されていない戻り値として返すことができます。

def genFn(a, b, c):
    # some initialisation / pre-computation
    startPt = fn(a, b, c)
    data = (yield startPt)
    while True:
        # perform some computation
        data = (yield result)

f = genFn(5, 6, 7)
startPt = f.send(None)  # first yield returns the start point
for data in dataseries[startPt:]:
    k = f.send(data)

ちなみに、.send(None)と同じ.next()です。

または、クラスを使用して、そのメソッドの1つとしてジェネレーターを使用することもできます。事前計算はで行われ__init__、データはインスタンス属性を介してアクセスできます。

class GenCl(object):
    def __init__(self, a, b, c):
        self.startPt = fn(a, b, c)

    def gen(self):
        startPt = self.startPt  # get the startPt calculated in __init__
        data = (yield None)
        while True:
            # perform some computation
            data = (yield result)

o = genCl(5, 6, 7)
startPt = o.startPt
f = o.gen()  # create the generator object
f.send(None)
for data in dataseries[startPt:]:
    k = f.send(data)

さらに別のアイデアは、クロージャを使用することです。関数呼び出しは、ジェネレーターと開始点を、たとえばタプルで返します。

def genFn(a, b, c):
    # some initialisation / pre-computation
    startPt = fn(a, b, c)
    def gen():  # actual generator function
        data = (yield None)
        while True:
            # perform some computation
            data = (yield result)
    return gen(), startPt  # returns generator and startPt

f, startPt = genFn(5, 6, 7)
f.send(None)
for data in dataseries[startPt:]:
    k = f.send(data)
于 2012-04-24T04:19:36.877 に答える
0

ジェネレーターに送信して特別な値を返すことができる特別なクラスを作成できます。

class GetStartPt:
    pass

def genFn(a, b, c):
    startPt = fn(a, b, c)
    data = (yield None)
    while True:
        if data is GetStartPt:
            data = (yield startPt)
            continue
        # compute here
        data = (yield result)

f = genFn(5, 6, 7)
f.send(GetStartPt)

ただし、このためのラッパークラスを作成する方がよい場合があります。

class GenClass(object):
     def __init__(self, a, b, c):
         self.startPt = fn(a, b, c)
         def generator(startPt, a, b c):
             data = (yield None)
                 while True:
                 # compute here
             data = (yield result)
         self._generator = generator(self.startPt, a, b, c)
     def __iter__(self):
         return self._generator
     def next(self):
         return self._generator.next()
     def send(self, value):
         return self.generator.send(value)
于 2012-04-24T03:12:21.417 に答える