我很好奇在python中使用静态变量,最后是:Why doesn't Python have static variables?
在接受的答案中,我发现信息量很大,据说“如果你希望每次调用函数的行为都会改变,那么你需要的是一个生成器”。
但是我有点困惑,因为那里使用的例子也可以用类来完成:
class Foo(object):
def __init__(self, bar):
self.bar = bar
def __call__(self):
self.bar = self.bar * 3 % 5
return self.bar
foo = Foo(bar)
print foo()
print foo()
这对我来说更有意义(但可能只是因为我之前没有正确使用过发电机)。
所以我的问题是,当函数需要在每次调用行为时都需要改变行为时,是否还有其他优点可以使用生成器。
答案 0 :(得分:3)
生成器(简单的,没有进入协同程序)有一个非常特定的目的:编写迭代器。为此,您可以隐式捕获局部变量和一个挂起的关键字(而不是“终止” - 您可以恢复)执行并为调用者提供迭代器的下一个值。优点是:
yield x
替换为results.append(x)
和return results
,并获得相当于list(the_original_generator(...))
的函数。self
来明确地使值长期存在 - 减少输入值,减少读取次数。你可以使用“捕获局部变量”的东西来实现一个行为的迭代,除了你可以有多个但你不调用函数但是使用迭代器({ {1}}代替next_val = next(vals)
)。是否合适取决于。
答案 1 :(得分:2)
对于一个你无法用类做的生成器,你无能为力。
使用生成器的原因很简单,它们更短,并且在许多情况下读取比类更自然。显然这取决于你正在做什么。在您给出的示例中,您只想重复执行相同的操作并吐出数字,因此生成器非常有意义。对于更复杂的情况,您可以使用一个类。
答案 2 :(得分:2)
正确的生成器类如下所示:
class Foo(object):
def __init__(self, bar):
self.bar = bar
def __iter__(self):
return self
def next(self):
self.bar = self.bar * 3 % 5
return self.bar
foo = Foo(3)
print next(foo)
print next(foo)
等效生成器函数占用代码的一半:
def Foo(bar):
while True:
bar = bar * 3 % 5
yield bar
foo = Foo(3)
print next(foo)
print next(foo)
生成器函数只是最常见的基本迭代模式的快捷方式。当你需要更复杂的东西时,一个类允许这样做。
答案 3 :(得分:1)
对于生成器,除了通过调用函数之外没有其他方法可以访问变量,而在基于类的变体中,您可以直接修改它。根据您的使用情况,这可能是优点和缺点。代码也更简单。有关更详细的讨论,请参阅:http://wiki.python.org/moin/Generators