use*_*872 1 python generator decorator
装饰器有没有办法将下面的函数转换为生成器?
@decorator_that_makes_func_into_generator
def countdown(n):
while n > 0:
print n,
n = n - 1
Run Code Online (Sandbox Code Playgroud)
必要时可以修改该功能.请注意,该函数没有yield语句,否则它已经是一个生成器.
如果你不能改变源的countdown,你必须捕获输出:
import sys
from io import StringIO
def decorator_that_makes_func_into_generator(func):
def wrapper(*a, **ka):
# Temporarily redirect all output to StringIO instance (intr)
ts, intr = sys.stdout, StringIO()
sys.stdout = intr
func(*a, **ka)
# Restore normal stdout from backup (ts)
sys.stdout = ts
# Get output from intr, split it by whitespace and use it as generator
yield from intr.getvalue().split()
return wrapper
@decorator_that_makes_func_into_generator
def countdown(n):
while n > 0:
print(n)
n = n - 1
print(countdown(5), list(countdown(5)))
# <generator object wrapper at 0x01E09058> ['5', '4', '3', '2', '1']
Run Code Online (Sandbox Code Playgroud)
如果你可以更改函数,如果你想从countdown(list或其他序列类型)返回一些东西,然后从返回的对象创建一个生成器,装饰器看起来像
def decorator_that_makes_func_into_generator(func):
def wrapper(*a, **ka):
yield from func(*a, **ka)
return wrapper
Run Code Online (Sandbox Code Playgroud)
注意:真棒yield from是在Python 3.3中引入的,旧版本使用普通循环代替:
for x in func(*a, **ka):
yield x
Run Code Online (Sandbox Code Playgroud)
例:
@decorator_that_makes_func_into_generator
def countdown(n):
res = []
while n > 0:
res.append(n)
n = n - 1
return res
print(type(countdown(5)), list(countdown(5)))
# Output: <class 'generator'> [5, 4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)
没有什么能阻止你申请decorator_that_makes_func_into_generator发电机:
@decorator_that_makes_func_into_generator
def countdown(n):
while n > 0:
yield n
n = n - 1
print(type(countdown(5)), list(countdown(5)))
# Outputs <class 'generator'> [5, 4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)
如果您不能更改该函数的主体,恐怕这太难了。
您尝试包装的函数不是生成器,即使将其包装到生成器中,该函数也会从头到尾地一次性执行。想必您不想要那样。
理论上你能做什么?
print()(在Python3中更轻松)| 归档时间: |
|
| 查看次数: |
864 次 |
| 最近记录: |