可选产量或 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]