我正在学习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')
我想使用这种编程方式(不要调用构造函数,或者至少隐式调用它)用于我自己的项目,但我无法理解它是如何工作的。
由于
答案 0 :(得分:6)
etree.parse
是一个Factory函数。它们的目的主要是构造对象(实例)的便捷方式。由于您可以通过looking at the source轻松验证,parse
函数几乎与第二个示例中的函数完全相同,只是它省略了一行代码或两行。
答案 1 :(得分:2)
在这种情况下,正在发生的事情是etree.parse()
函数正在为您创建ElementTree
对象并返回它。这就是为什么你不必亲自调用构造函数;它包含在parse
函数中。该函数创建一个ElementTree
实例,解析数据并修改新对象以正确表示已解析的信息。然后它returns
对象,所以你可以使用它(事实上,如果你看source,它基本上就是你在第二个例子中写的那样)。
这是面向对象编程中非常常见的习惯用语。从广义上讲,它被称为factory function。基本上,特别是对于复杂对象,需要做很多工作来创建对象的有用实例。因此,不是将大量逻辑打包到对象的构造函数中,而是创建一个或多个工厂函数来创建对象并根据需要进行配置。这意味着使用库开发的人可能有几种干净,简单的方法来实例化类,即使“实例化”实例化可能很复杂。
答案 2 :(得分:1)
在第一种情况下,您正在从模块调用辅助函数。它不是一个类方法(虽然在内部它可能会创建一个对象然后调用它的方法)。在第二种情况下,您将实例化一个对象,然后调用其方法。
答案 3 :(得分:1)
对于名为ClassName
的班级,调用ClassName()
隐含式调用__init__()
并返回ClassName
的新实例。
如果__init__
中未定义ClassName
,则会调用超级__init__
。
在你的情况下,这完全在函数内部:
def name(foo):
return ClassName(foo)
n = name("bar") # a function call returns a new instance