为什么csv.reader不被认为是一个类?

时间:2017-10-10 18:47:01

标签: python

根据我的理解,对象是类的实例。因此,由于csv.reader创建了一个reader对象,我认为它将被视为一个类。我对此非常陌生,所以如果有人能为我澄清这一点会很有帮助。

3 个答案:

答案 0 :(得分:4)

如果某事物是一个物体,它通常不是一个阶级 就像动物物种一样。

名为Cujo的狗属于犬种,但Cujo不是物种(类别)本身。 你可以创建一条狗,例如由:

dog = Dog ('Cujo')

我可以上恐龙课程,但不再有那个班级的生物了。

不仅类可以返回对象。我可以有如下功能:

def dog_factory (name):
    return Dog (name)

要创建一只狗,你可以说:

dog = dog_factory ('Cujo')

虽然Dog是一个类,但dog_factory只是一个函数。 它使用该类来创建一条狗。

如果您要求上课,请使用type (dog), 你会看到那只狗是狗类,而不是类dog_factory。

如果您碰巧知道,请不要对JavaScript中的情况感到困惑。 真正基于类的语言,如C ++,Java,C#和Python是完全不同的, 并且在我看来不那么扭曲了。

答案 1 :(得分:3)

并非创建对象的所有内容都是类。 创建对象的大多数可调用对象不是类,并且每个可调用对象都返回一个对象,除非它根本不返回任何内容(例如,通过抛出异常)。例如,

def f():
    return []

创建并返回一个列表对象,但它不是一个类。

至于为什么csv.reader没有特别编写为类,这似乎是csv模块的历史发展的工件。建议模块reader的原始PEP应该是一个函数:

  

使用阅读器工厂功能

创建CSV阅读器

但这只是将问题从“为什么reader不是一个阶级”转移到“为什么PEP说它不应该是一个阶级”,而PEP没有给出理由。

一种可能性是允许工厂函数返回多种读取器类型,尽管似乎从未探索过。另一个假设是模块从代码中下降到很久以后 使用工厂函数。

csv.reader会返回读者类型written in C的实例,并且CSV PEP会建议代码可能基于earlier C module这么久以前的type-class unification。在类型类统一之前,用C 编写的类型不能直接调用。您编写工厂函数来创建C类型的实例。这甚至扩展到内置类型,如listint;那时候,像listint这样的名称就是创建list和int对象的工厂函数,而不是引用类型本身。

在Python 2.2中,类型级统一使得C类型可以调用,但是使用早期系统设计的代码仍然具有工厂函数,并不一定有任何令人信服的理由去除它们。

答案 2 :(得分:1)

来自PEP 305

  

使用阅读器工厂功能创建CSV阅读器:

obj = reader(iterable [, dialect='excel']
             [optional keyword args])

所以csv.reader正式是函数,而不是类。

如果csv.reader是一个类,而isinstance(my_reader, csv.reader)返回True,我可能会认为更有意义,我同意你的看法。这就是csv.DictReader如何做到的:

>>> import io, csv
>>> reader = csv.DictReader(io.StringIO())
>>> isinstance(reader, csv.DictReader)
True

不幸的是,CPython代码定义读者并将其公开给csv.py模块的机制并没有经过深思熟虑。而是csv imports the name reader from a _csv module,它通常作为.so(二进制)文件的编译代码分发。

在内部,csv阅读器是type(_csv.reader(...))类的一个实例,并且该类本身未公开。因此,如果你想要进行类型检查,你需要像这样做一些hacky:

>>> import io, csv
>>> csv.Reader = type(csv.reader(io.StringIO()))
>>> isinstance(csv.reader(io.StringIO()), csv.Reader)
True

作为一个与真实实现更紧密匹配的心理模型,您可以将其视为返回对象的辅助函数:

def reader(*args, **kwargs):
    return _csv.reader(*args, **kwargs)

没有什么特别的原因,CPython开发人员无法公开课程并将其称为csv.Reader,但事实并非如此。 csv模块目前大约有15年的历史,它早于Python对象模型的清理,其中类型和类的约定更好地建立。不幸的是,由于向后兼容性问题,他们现在无法将实施从csv.reader功能更改为csv.Reader类。