静态变量模拟:类与生成器
我对在 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技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
生成器(简单的生成器,不涉及协程)有一个非常具体的目的:编写迭代器。为此,您可以隐式捕获局部变量和用于暂停(与“终止”相反 - 您可以恢复)执行的关键字,并向调用者提供迭代器的下一个值。优点是:
yield x
替换为results.append(x)
并在末尾替换return results
并获得与list 等效的函数(the_original_generator(...))
。self
中来显式地使值长期存在 - 更少的输入和更少的阅读。您可以使用“捕获局部变量”来实现一个可迭代的行为,除了您可以有多个可迭代并且您不调用函数而是使用迭代器(
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:
yield x
withresults.append(x)
andreturn results
at the end and get a function that's equivalent tolist(the_original_generator(...))
.self
- less to type and less to read.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 ofnext_val = vals()
). Whether it is appropriate depends.对于生成器来说,没有什么是类做不到的。
使用生成器的原因很简单,因为它们更短,并且在许多情况下比类更容易阅读。显然这取决于你在做什么。在您给出的示例中,您只想重复执行相同的操作并吐出数字,因此生成器非常有意义。对于更复杂的情况,您可以使用类。
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.
正确的生成器类如下所示:
等效的生成器函数只需要一半的代码:
生成器函数只是最常见、基本迭代模式的快捷方式。当您需要更复杂的东西时,类可以满足您的需求。
A proper generator class looks like this:
The equivalent generator function takes half the code:
Generator functions are just a shortcut for the most common, basic iteration pattern. When you need something more complex a class allows for that.
对于生成器来说,除了调用函数之外,没有其他方法可以访问变量,而在基于类的变体中,您可以直接修改它。根据您的用例,这既可能是优点,也可能是缺点。而且代码也比较简单。有关更详细的讨论,请参阅: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