擅长:python、mysql、java
<p>作为<code>itertools</code>的类实现有一些生成器函数没有的优点。例如:</p>
<ol>
<li>CPython在C层实现这些内建,在C层,生成器“函数”最好实现为实现<code>__next__</code>的类,该类将状态保留为实例属性;<code>yield</code>的生成器是Python层的精确性,而且实际上,它们只是<code>generator</code>类的一个实例(因此它们实际上仍然是类实例,就像Python中的其他所有实例一样)</li>
<li>生成器不可pickle或copyable,也没有“story”来让它们支持这两种行为(内部状态太复杂和不透明,无法将其泛化);一个类可以定义<code>__reduce__</code>/<code>__copy__</code>/<code>__deepcopy__</code>(如果它是Python级别的类,则可能根本不需要这样做;它将自动工作)并使实例可pickle/copyable(因此,如果您已经从<code>range</code>迭代器生成了5个元素,那么您可以复制或pickle/unpickle它,并在迭代中获得相同距离的迭代器)</li>
</ol>
<p>对于非发电机工具,原因通常是相似的。类可以被赋予一个函数所不能的状态和自定义行为,它们可以被继承(如果需要的话,但是C层类可以禁止子类化,如果它们是“逻辑”函数)。在</p>
<p>它对于动态实例创建也很有用;如果您有一个未知类的实例,但有一个已知的原型(比如,接受iterable的序列构造函数,或者<code>chain</code>或其他任何类型),并且您想将其他类型转换为该类,则可以执行<code>type(unknown)(constructorarg)</code>;如果它是生成器,<code>type(unknown)</code>是无用的,则不能使用它来创建更多这本身是因为你不能反省来找出它是从哪里来的(不是以合理的方式)。在</p>
<p>除此之外,即使您从未使用过编程逻辑的特性,您更希望在交互解释器中看到什么,或者在<code>type(myiter)</code>,<code><class 'generator'></code>的打印调试中看到什么,它没有给出关于来源的提示,或者{<cd14>}确切地告诉您您拥有什么和它来自何处?在</p>