[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