I am learning python, step-by-step. Today is about Object Oriented Programming. I know how to create and use simple classes, but something bugs me. Most of the objects I use in python do not require to call a constructor
How can this works? Or is the constructor called implicitly? Example:
>>> 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>
(from http://www.diveinto.org/python3/xml.html#xml-parse)
I would have gone this way (which actually works):
>>> import xml.etree.ElementTree as etree
>>> tree = etree.ElementTree() # instanciate object
>>> tree.parse('examples/feed.xml')
I'd like to use this way of programming (do not call constructor, or at least call it implicitly) for my own project, but I can't get how it really works.
Thanks
4 Answers 4
etree.parse is a Factory function. Their purpose is mainly to be convenient ways of constructing objects (instances). As you can easily verify by looking at the source, the parse function does almost exactly as you do in your second example except it ommits a line of code or two.
4 Comments
self parameter means. A function, on the other hand, sits at the module level and is not implicitly given a reference to an object instance, so it must create one if one is needed.classmethod (very useful for alternate constructors), a staticmethod, or even an unbound instancemethod (in which case you have to explicitely pass the instance).In this case, what's happening is that the etree.parse() function is creating the ElementTree object for you, and returning it. That's why you don't have to call a constructor yourself; it's wrapped up in the parse function. That function creates an ElementTree instance, parses the data and modifies the new object to correctly represent the parsed information. Then it returns the object, so you can use it (in fact, if you look at the source, it does essentially what you wrote in your second example).
This is a pretty common idiom in object-oriented programming. Broadly speaking, it's called a factory function. Basically, especially for complex objects, a lot of work is required to create a useful instance of the object. So, rather than pack a lot of logic into the object's constructor, it's cleaner to make one or more factory functions to create the object and configure it as needed. This means that someone developing with the library may have several clean, simple ways to instantiate the class, even if "under the hood" that instantiation may be complex.
Comments
In the first case, you are calling a helper function from the module. Its not a class method (though internally it might create an object and then call its method). In the second case, you are instantiating an object and then calling its method.
Comments
For a class named ClassName, calling ClassName() implicity calls __init__() and returns you a new instance of ClassName.
If __init__ is not defined in ClassName, the super's __init__ will be called.
In your case, this is all inside a function:
def name(foo):
return ClassName(foo)
n = name("bar") # a function call returns a new instance
.parse()function creates an object for you. Functions can do that; do stuff then return the result. Why is that surprising?__init__with an empty method.__init__is one, but there are many others. You should look into the__call__method, which relates to your question and what you want to do, even though you won't be able to do it with a factory function. rafekettler.com/magicmethods.html#callable