情况:
Python 2.7代码,包含许多“yield”语句。但规格已发生变化。 每个yield都会调用一个用于始终返回值的函数。现在结果有时是应该产生的值,但有时候不应该产生任何价值。
哑巴示例:
在:
def always(x):
return 11 * x
def do_stuff():
# ... other code; each yield is buried inside an if or other flow construct ...
# ...
yield always(1)
# ...
yield always(6)
# ...
yield always(5)
print( list( do_stuff() ) )
=>
[11, 66, 55]
AFTER(如果我可以使用Python 3,但目前不是一个选项):
def maybe(x):
""" only keep odd value; returns list with 0 or 1 elements. """
result = 11 * x
return [result] if bool(result & 1) else []
def do_stuff():
# ...
yield from maybe(1)
# ...
yield from maybe(6)
# ...
yield from maybe(5)
=>
[11, 55]
AFTER(在Python 2.7中):
def maybe(x):
""" only keep odd value; returns list with 0 or 1 elements. """
result = 11 * x
return [result] if bool(result & 1) else []
def do_stuff():
# ...
for x in maybe(1): yield x
# ...
for x in maybe(6): yield x
# ...
for x in maybe(5): yield x
注意:在我翻译的实际代码中,“yield”被隐藏在各种流控制结构中。而“可能”功能有两个参数,而且更复杂。
我的问题:
注意每次调用“maybe”都会返回1个值来生成,或者返回0个值。 (更改“可能”以返回值,或者在没有值的情况下返回“无”,如果有帮助,则可以。)
鉴于这种0/1的情况,还有更简洁的代码方式吗?
答案 0 :(得分:1)
如果你说你可以退回None
,那么我会把代码保留在原来的位置:
def maybe(x):
""" only keep odd value; returns either element or None """
result = 11 * x
if result & 1: return result
def do_stuff():
yield maybe(1)
yield maybe(6)
yield maybe(5)
但使用包装版本而不是None
s,如:
def do_stuff_use():
return (x for x in do_stuff() if x is not None)
如果你愿意的话,你甚至可以将整件事装在装饰师中:
import functools
def yield_not_None(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
return (x for x in f(*args, **kwargs) if x is not None)
return wrapper
@yield_not_None
def do_stuff():
yield maybe(1)
yield maybe(6)
yield maybe(5)
之后
>>> list(do_stuff())
[11, 55]