[Tutor] method, type?

Steven D'Aprano steve at pearwood.info
Thu Jan 7 23:24:16 EST 2016


On Fri, Jan 08, 2016 at 12:02:44PM +1100, Cameron Simpson wrote:
> On 08Jan2016 00:18, ALAN GAULD <alan.gauld at btinternet.com> wrote:
> >My only point of difference here, I think, is the definition
> >of a constructor. I consider a constructor to be the creator
> >of object instances, which makes the only default Python
> >constructor the __new__() since the __init__() is only an
> >initializer.
> 
> Me too. I was deliberately avoiding the term "constructor", then let myself 
> get sucked into using it just now because you get a new instance of your 
> target class out of the factory function/method. But they are better 
> thought of as wrappers for the class' real constructor.

I maintain that "constructor" for the most part has to be understood of 
a statement of intention, not a hard definition. Apart from __new__ 
itself, which genuinely is special, "constructor" in a language like 
Python refers to the intention of creating new instances, as opposed to 
"doing some work".

For example, consider something like str.upper(). It returns a new 
string object. Does that make it a constructor? No, because the intent 
is to do work on a string (convert it to uppercase), and creating a new 
string is just a means to an end.

As I showed in a previous email, it is not necessary for a constructor 
to call __new__. It can do the work of creating a new instance itself, 
if the author chooses. But generally, that's just duplicating effort.

And likewise, even though __new__ is special, it doesn't have to be used 
as a constructor. Python supports classes with no default constructor, 
or one that returns something other than an instance of the class. Just 
arrange matters for __new__ to return something other than an instance 
of its own class:

class MyClass:
    def __new__(cls):
        return "Surprise!"

Surprising though this is, it is actually allowed, and the Python 
interpreter takes special care to ensure that it works correctly.

(In detail, when you call a class x = MyClass(), that calls __new__. If 
__new__ returns an instance of MyClass, Python then automatically calls 
__init__ as well. But if it is an instance of something else, then 
Python skips calling __init__ so as to prevent it being called twice.)

So my rule of thumb is, assuming that there's nothing funny going on:

(1) __new__ is the default constructor;

(2) __init__ is the initialiser, but sometimes we're lazy and call it 
the constructor;

(3) If you see a CLASS method called "from_foo" or similar, which 
returns an instance of the class, that's probably an alternate 
(non-default) constructor;

(4) But we usually don't count methods which take an instance of the 
class, and transform or copy them in some way as "constructors" even if 
they do in fact construct a new instance.



-- 
Steve


More information about the Tutor mailing list