Python 如何在生成器函数对象实例中存储和检索元信息?

Python 如何在生成器函数对象实例中存储和检索元信息?,python,Python,有没有一种方法可以向实例化生成器函数的调用方返回比函数实例本身更多的信息 比如说, 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,

有没有一种方法可以向实例化生成器函数的调用方返回比函数实例本身更多的信息

比如说,

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

您可以创建一个特殊类,该类可以发送到生成器,以使其返回您的特殊值

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)

您可以将其作为第一次
send
call当前未使用的返回值返回

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()
相同

或者,您可以使用一个类并将generator用作其方法之一。预计算将在
\uuuu init\uuuu
中完成,数据可以通过实例属性访问

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)

为什么不在发送
None
时退回呢?谢谢。我想你的方法1正是我所需要的。这是令人惊讶的简单-我不知道我们可以使用第一次发送(无)返回结果。其他两种方法虽然更面向对象,但需要更多的代码和维护。