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

发布于 2024-12-10 00:19:10 字数 975 浏览 0 评论 0原文

我对在 python 中使用静态变量感到好奇,最终得到: 为什么 Python 不这样做有静态变量?

在我发现信息丰富的已接受答案中,据说“如果您希望函数的行为在每次调用时都会改变,那么您需要的是一个生成器”。

然而我有点困惑,因为那里使用的示例也可以用一个类来完成:

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()

这对我来说更有意义(但可能只是因为我以前没有正确使用生成器)。

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

I was curious about using static variables in python, and ended up at: Why doesn't Python have static variables?

In the accepted answer, which I found informative, it is said "If you want your function's behavior to change each time it's called, what you need is a generator".

However I was a bit confused, since the example used there can be done with a class as well:

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()

This makes more sense to me (but probably only because I haven't used generators properly before).

So my question is whether there is some other advantage to using generators over classes when the function needs to change behavior each time it's called.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

可可 2024-12-17 00:19:10

生成器(简单的生成器,不涉及协程)有一个非常具体的目的:编写迭代器。为此,您可以隐式捕获局部变量和用于暂停(与“终止”相反 - 您可以恢复)执行的关键字,并向调用者提供迭代器的下一个值。优点是:

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

可以使用“捕获局部变量”来实现一个可迭代的行为,除了您可以有多个可迭代并且您不调用函数而是使用迭代器(next_val = next(vals) 而不是 next_val = vals())。是否合适要看情况。

Generators (the simple ones, not getting into coroutines) have a single, very specific purpose: Writing iterators. To this end, you get implicit capture of local variable and a keyword to suspend (as opposed to "terminate" - you can resume) execution and give the caller the next value of the iterator. The advantages are:

  • The logic reads more naturally, as you don't need to chop it into several method invokations - all state is preserved, including the program counter - you can use control flow across yielding . You could replace yield x with results.append(x) and return results at the end and get a function that's equivalent to list(the_original_generator(...)).
  • You don't need to explicitly make values long-lived by putting them into self - less to type and less to read.
  • You don't need a class declaration with two method declarations (a few lines of boilerplate, which is considerable by Python standards).

You can use the "capture of local variable" thing to implement an iterable which behaves as, except that you can have multiple ones and you don't invoke a function but use an iterator (next_val = next(vals) instead of next_val = vals()). Whether it is appropriate depends.

︶葆Ⅱㄣ 2024-12-17 00:19:10

对于生成器来说,没有什么是类做不到的。

使用生成器的原因很简单,因为它们更短,并且在许多情况下比类更容易阅读。显然这取决于你在做什么。在您给出的示例中,您只想重复执行相同的操作并吐出数字,因此生成器非常有意义。对于更复杂的情况,您可以使用类。

There's nothing you can do with a generator that you couldn't do with a class.

The reason to use generators is simply that they're shorter, and in many cases read more naturally than classes. Obviously this depends what you're doing. In the example you give, you just want to repeatedly perform the same operations and spit out the number, so a generator makes perfect sense. For more complex situations, you'd use a class.

云仙小弟 2024-12-17 00:19:10

正确的生成器类如下所示:

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)

生成器函数只是最常见、基本迭代模式的快捷方式。当您需要更复杂的东西时,类可以满足您的需求。

A proper generator class looks like this:

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)

The equivalent generator function takes half the code:

def Foo(bar):
    while True:
        bar = bar * 3 % 5   
        yield bar                                                          

foo = Foo(3)                                                                  
print next(foo)                                                                     
print next(foo)

Generator functions are just a shortcut for the most common, basic iteration pattern. When you need something more complex a class allows for that.

梦行七里 2024-12-17 00:19:10

对于生成器来说,除了调用函数之外,没有其他方法可以访问变量,而在基于类的变体中,您可以直接修改它。根据您的用例,这既可能是优点,也可能是缺点。而且代码也比较简单。有关更详细的讨论,请参阅:http://wiki.python.org/moin/Generators

For generators there's no other way to access the variable, except by calling a function, while in a class-based variant, you can modify it directly. This can be both advantage and disadvantage depending on your use-case. Also the code is simpler. For a more detailed discussion see: http://wiki.python.org/moin/Generators

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文