2

我正在一步一步地学习python。今天是关于面向对象的编程。我知道如何创建和使用简单的类,但有些东西让我很头疼。我在python中使用的大多数对象都不需要调用构造函数

这怎么行?还是隐式调用构造函数?例子:

>>> import xml.etree.ElementTree as etree    
>>> tree = etree.parse('examples/feed.xml')  
>>> root = tree.getroot()                    
>>> root
<Element {http://www.w3.org/2005/Atom}feed at cd1eb0>

(来自http://www.diveinto.org/python3/xml.html#xml-parse

我会这样(实际上有效):

>>> import xml.etree.ElementTree as etree 
>>> tree = etree.ElementTree() # instanciate object
>>> tree.parse('examples/feed.xml')

我想在我自己的项目中使用这种编程方式(不要调用构造函数,或者至少隐式调用它),但我不知道它是如何工作的。

谢谢

4

4 回答 4

6

etree.parse是一个工厂函数。它们的目的主要是作为构造对象(实例)的便捷方式。正如您可以通过查看源代码轻松验证的那样,该parse函数几乎与您在第二个示例中所做的完全相同,只是它省略了一两行代码。

于 2013-06-20T14:25:33.287 回答
2

在这种情况下,发生的事情是该etree.parse()函数正在ElementTree为您创建对象并返回它。这就是为什么您不必自己调用构造函数的原因;它包含在parse函数中。该函数创建一个ElementTree实例,解析数据并修改新对象以正确表示解析的信息。然后它returns是对象,因此您可以使用它(实际上,如果您查看source,它基本上可以执行您在第二个示例中编写的内容)。

这是面向对象编程中非常常见的习语。从广义上讲,它被称为工厂函数。基本上,特别是对于复杂的对象,创建一个有用的对象实例需要做很多工作。因此,与其将大量逻辑打包到对象的构造函数中,不如创建一个或多个工厂函数来创建对象并根据需要对其进行配置。这意味着使用该库进行开发的人可能有几种干净、简单的方法来实例化该类,即使“在幕后”该实例化可能很复杂。

于 2013-06-20T14:25:17.563 回答
1

在第一种情况下,您正在从模块中调用辅助函数。它不是类方法(尽管在内部它可能会创建一个对象然后调用它的方法)。在第二种情况下,您正在实例化一个对象,然后调用它的方法。

于 2013-06-20T14:25:04.210 回答
1

对于名为 的类ClassNameClassName()隐式调用__init__()会调用并返回一个新的ClassName.

如果__init__未在 中定义,则将调用ClassNamesuper 。__init__

在您的情况下,这一切都在一个函数中:

def name(foo):
    return ClassName(foo)

n = name("bar") # a function call returns a new instance
于 2013-06-20T14:28:48.147 回答