[英]Optional yield or return in python3. How to?
我想要一个可以选择返回或产生结果的函数。 这是一个例子。
def f(option=True):
...
for...:
if option:
yield result
else:
results.append(result)
if not option:
return results
当然,这行不通,我尝试过使用 python3,无论我设置什么选项值,我总是得到一个生成器。 据我所知,python 检查函数的主体,如果存在yield
,则结果将是一个生成器。 有什么办法可以解决这个问题并制作一个可以随意返回或产生的函数吗?
你不能。 任何使用yield
都会使函数成为生成器。
您可以使用一个使用list()
将生成器生成的所有值存储在列表对象中并返回的函数来包装您的函数:
def f_wrapper(option=True):
gen = f()
if option:
return gen # return the generator unchanged
return list(gen) # return all values of the generator as a list
然而,一般来说,这是糟糕的设计。 不要让你的函数像这样改变行为; 坚持一种返回类型(生成器或对象),不要在两者之间切换。
考虑将其拆分为两个函数:
def f():
yield result
def f_as_list():
return list(f())
如果您需要生成器,请使用f()
,如果您想要一个列表,请使用f_as_list()
。
由于list()
,(和next()
仅访问生成器的一个值)是内置函数,因此您很少需要使用包装器。 直接调用这些函数:
# access elements one by one
gen = f()
one_value = next(gen)
# convert the generator to a list
all_values = list(f())
那这个呢?
def make_f_or_generator(option):
def f():
return "I am a function."
def g():
yield "I am a generator."
if option:
return f
else:
return g
这至少让您可以选择创建函数或生成器。
基于class
的方法
class FunctionAndGenerator:
def __init__(self):
self.counter = 0
def __iter__(self):
return self
# You need a variable to indicate if dunder next should return the string or raise StopIteration.
# Raising StopIteration will stop the loop from iterating more.
# You'll have to teach next to raise StopIteration at some point
def __next__(self):
self.counter += 1
if self.counter > 1 :
raise StopIteration
return f"I'm a generator and I've generated {self.counter} times"
def __call__(self):
return "I'm a function"
x = FunctionAndGenerator()
print(x())
for i in x:
print(i)
I'm a function
I'm a generator and I've generated 1 times
[Program finished]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.