我有我需要挂钩的某些功能,这样我可以检查返回值和追踪他们的情况。 这是例如通过运行方法/函数返回值的平均值追踪有用的。 然而,这些方法/功能也可以是发电机。
但是,如果我没有错,在解析时蟒蛇检测发电机和当函数被调用运行时,它总是返回一个发电机。 因此,我不能简单地做一些事情,如:
import types
def decorator(func):
average = None # assume average can be accessed by other means
def wrap(*args, **kwargs):
nonlocal average
ret_value = func(*args, **kwargs)
#if False wrap is still a generator
if isinstance(ret_value, types.GeneratorType):
for value in ret_value:
# update average
yield value
else:
# update average
return ret_value # ret_value can't ever be fetched
return wrap
而yield
在这个装饰ING是必要的,因为我需要跟踪的值作为主叫迭代这个装饰发生器(即“实时”)。 意思是,我不能简单地取代for
,并yield
与values = list(ret_value)
并返回values
。 (IE)如果func
是它需要保持装饰一旦发电机发电机。 但是,如果func
是一个纯函数/方法,即使else
执行, wrap
仍然是一个发电机。 这意味着,该ret_value
永远不能被取出。
使用这样的发电机将是一种玩具例如:
@decorated
def some_gen(some_list):
for _ in range(10):
if some_list[0] % 2 == 0:
yield 1
else:
yield 0
def caller():
some_list = [0]
for i in some_gen(some_list):
print(i)
some_list[0] += 1 # changes what some_gen yields
对于玩具的例子,有可能是简单的解决方案,但它只是为了证明这一点。
也许我失去了一些东西很明显,但我做了一些研究,并没有发现任何东西。 我发现的最接近的事情是这个 。 但是,这仍然没有让装饰检查由包发生器(只是第一)返回的每一个值。 这是否有一个解决方案,或两种类型的装饰(一个功能,一个用于装饰)必要的?