为什么许多Python内置/标准库函数实际上是类 [英] Why are many Python built-in/standard library functions actually classes
问题描述
许多Python内置的函数实际上是类,尽管它们也具有直接的函数实现。甚至是非常简单的代码,例如 itertools.repeat
。这样做的动机是什么?
Many Python builtin "functions" are actually classes, although they also have a straightforward function implementation. Even very simple ones, such as itertools.repeat
. What is the motivation for this? It seems like over-engineering to me.
编辑:我不是在问 itertools.repeat
的目的。或任何其他特定功能。这只是一个非常简单的函数的示例,它具有非常简单的可能的影响:
I am not asking about the purpose of itertools.repeat
or any other particular function. It was just an example of a very simple function with a very simple possible impementation:
def repeat(x):
while True: yield x
但是 itertools.repeat
实际上不是函数,而是作为类实现的。我的问题是:为什么?似乎是不必要的开销。
But itertools.repeat
is not actually a function, it's implemented as a class. My question is: Why? It seems like unnecessary overhead.
我也了解类是可调用的函数,以及如何使用类来模拟类似函数的行为。但是我不明白为什么它在标准库中如此广泛地使用。
Also I understand that classes are callable functions and how you can emulate a function-like behavior using a class. But I don't understand why it's so widely used through the standard library.
推荐答案
作为<$ c $的类实现c> itertools 具有一些生成器函数没有的优点。例如:
Implementing as a class for itertools
has some advantages that generator functions don't have. For example:
- CPython在C层实现了这些内置函数,而在C层,最好实现生成器函数作为实现
__ next __
的类,该类将状态保留为实例属性;基于yield
的生成器是Python的一个很好的方面,实际上,它们只是generator
类的一个实例(因此它们实际上仍然是类实例,就像Python中的其他所有对象一样) - 生成器不可腌制或可复制,并且没有故事来使它们支持任何一种行为(内部状态过于复杂和不透明,无法将其概括化;一个类可以定义
__ reduce __
/__ copy __
/__ deepcopy __
(和如果是Python级别的类,则可能甚至不需要这样做;它会自动工作)并使实例可腌制/可复制(因此,如果您已经从range生成了5个元素
迭代器,您可以将其复制或腌制/解开,并在迭代中获得相同的距离)
- CPython implements these built-ins at the C layer, and at the C layer, a generator "function" is best implemented as a class implementing
__next__
that preserves state as instance attributes;yield
based generators are a Python layer nicety, and really, they're just an instance of thegenerator
class (so they're actually still class instances, like everything else in Python) - Generators aren't pickleable or copyable, and don't have "story" for making them support either behavior (the internal state is too complex and opaque to generalize it); a class can define
__reduce__
/__copy__
/__deepcopy__
(and if it's a Python level class, it probably doesn't even need to do that; it will work automatically) and make the instances pickleable/copyable (so if you have already generated 5 elements from arange
iterator, you can copy or pickle/unpickle it, and get an iterator the same distance along in iteration)
对于非生成器工具,原因通常相似。可以为类赋予状态,而某些功能则无法提供自定义行为。它们可以继承(如果需要的话,但是C层类如果是逻辑上的函数,则可以禁止子类化。)。
For non-generator tools, the reasons are usually similar. Classes can be given state and customized behaviors that a function can't. They can be inherited from (if that's desired, but C layer classes can prohibit subclassing if they're "logically" functions).
对于动态实例创建也很有用;如果您有一个未知类的实例但一个已知原型的实例(例如,采用可迭代或 chain
之类的序列构造函数),并且您想要转换其他输入该类,您可以执行 type(unknown)(constructorarg)
;如果它是一个生成器,则 type(unknown)
是没有用的,则您不能用它来使自身更多,因为您不能反省它的来源(
It's also useful for dynamic instance creation; if you have an instance of an unknown class but a known prototype (say, the sequence constructors that take an iterable, or chain
or whatever), and you want to convert some other type to that class, you can do type(unknown)(constructorarg)
; if it's a generator, type(unknown)
is useless, you can't use it to make more of itself because you can't introspect to figure out where it came from (not in reasonable ways).
此外,即使您从未使用过编程逻辑功能,您还是希望在交互式解释器中进行打印调试或查看 type(myiter)
,< class'generator'>
,它没有任何关于起源的提示,或< class'itertools.repeat'>
可以告诉您确切的信息以及它的来源?
And beyond that, even if you never use the features for programming logic, what would you rather see in the interactive interpreter or doing print debugging of type(myiter)
, <class 'generator'>
that gives no hints as to origin, or <class 'itertools.repeat'>
that tells you exactly what you have and where it came from?
这篇关于为什么许多Python内置/标准库函数实际上是类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!