The right way to 'call' a class attribute inside the same class

Ben Finney ben+python at benfinney.id.au
Mon Dec 12 18:17:03 EST 2016


Ned Batchelder <ned at nedbatchelder.com> writes:

> Claiming that __init__ isn't a constructor seems overly pedantic to
> me.

Whereas to me, claiming that ‘Foo.__init__’ is a constructor seems
needlessly confusing.

* Classes already have a constructor, ‘Foo.__new__’. If we call
  something else the constructor, what do we call ‘__new__’? Are they
  both constructors?

* A constructor for Foo should start from “no instance” and result in
  “an instance of Foo”. ‘Foo.__init__’ does not do that; ‘Foo.__new__’
  does.

* A constructor should return the instance. ‘Foo.__init__’ does not do
  that; ‘Foo.__new__’ does.

If the differences didn't matter I would agree that “overly pedantic” is
fair. But those differences trip up newcomers. Thinking of
‘Foo.__init__’ leads people to wonder where the ‘self’ attribute came
from – am I not meant to be constructing it? — and to attempt to return
that instance. And when the time comes to lean about ‘__new__’ the
confusion continues, because the newcomer has been told that something
*else* is the constructor, so what's this?

> What's true is that Python's constructors (__init__) are different than
> C++ constructors.  In C++, you don't have an object of type T until the
> constructor has finished. In Python, you have an object of type T before
> __init__ has been entered.

I'm not going to argue that C++ should define terminology for other
languages. But “constructor” should have a close correlation with the
normal English-language meaning of the term.

That meaning matches ‘Foo.__new__’, which makes that method a
constructor. It does not match ‘Foo.__init__’, which makes that method
not a constructor.

> The reason to call __init__ a constructor is because of what is the
> same between C++ and Python: the constructor is where the author of
> the class can initialize instances of the class.

So you've just described what ‘Foo._init__’ does: it initialises the
existing instance. That's why it is better to call it the “initialiser”,
a term we already have and use correctly.

-- 
 \     “DRM doesn't inconvenience [lawbreakers] — indeed, over time it |
  `\     trains law-abiding users to become [lawbreakers] out of sheer |
_o__)                        frustration.” —Charles Stross, 2010-05-09 |
Ben Finney



More information about the Python-list mailing list