可选产量或 return in python3。如何?
Optional yield or return in python3. How to?
我想要一个函数,可以选择 return 或产生结果。
这是一个例子。
def f(option=True):
...
for...:
if option:
yield result
else:
results.append(result)
if not option:
return results
当然,这是行不通的,我已经尝试过 python3,无论我设置什么选项值,我总是能得到一个生成器。
据我所知,python 检查函数体,如果 yield
存在,那么结果将是一个生成器。
有什么办法可以解决这个问题并制作一个可以 return 或随意 yield 的函数吗?
你不能。 使用 yield
使函数成为生成器。
您可以用一个函数包装您的函数,该函数使用 list()
来存储生成器在列表对象中生成的所有值,并且 return 是:
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
但是,一般来说,这是糟糕的设计。不要让你的函数像这样改变行为;坚持一种 return 类型(生成器 或 对象)并且不要在两者之间切换。
考虑将其拆分为两个函数:
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]
我想要一个函数,可以选择 return 或产生结果。 这是一个例子。
def f(option=True):
...
for...:
if option:
yield result
else:
results.append(result)
if not option:
return results
当然,这是行不通的,我已经尝试过 python3,无论我设置什么选项值,我总是能得到一个生成器。
据我所知,python 检查函数体,如果 yield
存在,那么结果将是一个生成器。
有什么办法可以解决这个问题并制作一个可以 return 或随意 yield 的函数吗?
你不能。 使用 yield
使函数成为生成器。
您可以用一个函数包装您的函数,该函数使用 list()
来存储生成器在列表对象中生成的所有值,并且 return 是:
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
但是,一般来说,这是糟糕的设计。不要让你的函数像这样改变行为;坚持一种 return 类型(生成器 或 对象)并且不要在两者之间切换。
考虑将其拆分为两个函数:
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]