静态变量模拟:类与生成器

时间:2011-10-16 11:31:21

标签: python class generator static-variables

我很好奇在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()

这对我来说更有意义(但可能只是因为我之前没有正确使用过发电机)。

所以我的问题是,当函数需要在每次调用行为时都需要改变行为时,是否还有其他优点可以使用生成器。

4 个答案:

答案 0 :(得分:3)

生成器(简单的,没有进入协同程序)有一个非常特定的目的:编写迭代器。为此,您可以隐式捕获局部变量和一个挂起的关键字(而不是“终止” - 您可以恢复)执行并为调用者提供迭代器的下一个值。优点是:

  • 逻辑读取更自然,因为您不需要将其切换为多个方法调用 - 所有状态都被保留,包括程序计数器 - 您可以使用控制流跨过屈服。您可以在最后将yield x替换为results.append(x)return results,并获得相当于list(the_original_generator(...))的函数。
  • 您不需要通过将值放入self来明确地使值长期存在 - 减少输入值,减少读取次数。
  • 您不需要具有两个方法声明的类声明(几行样板文件,这是Python标准相当的)。

可以使用“捕获局部变量”的东西来实现一个行为的迭代,除了你可以有多个但你不调用函数但是使用迭代器({ {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