Python constructors have particular semantics, and ‘Foo.__init__’ doesn't qualify

Thomas 'PointedEars' Lahn PointedEars at web.de
Wed Dec 14 23:14:18 EST 2016


Ben Finney wrote:

> Chris Angelico <rosuav at gmail.com> writes:
>> On Tue, Dec 13, 2016 at 10:17 AM, Ben Finney <ben+python at benfinney.id.au>
>> wrote:
>> > 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?
>>
>> In JavaScript [different semantics apply].
>>
>> Ultimately, every language has slightly different semantics […], so
>> you have to learn that the "constructor" might have slightly different
>> semantics.

Actually, that is an inverse semantic fallacy.  There *is* always *some* 
common semantics to a the same term used in different domains; that is *why* 
it is used across domains (here: across object-oriented programming 
languages).  The common semantics here appears to be, as I substantiated by 
the FOLDOC reference, that a constructor initializes an object/instance.

“construct” does _not_ mean the same as “create” (make); understood 
literally, it means “heap together”, “build” (from Latin «construo», from 
«com» “together” + «struo» “I heap up, pile”).  A “constructor” is then the 
person or (here) the thing that “heaps together”.  ISTM that it “heaps 
together” the properties/attributes so that the object can be useful.

This is the same in Python as in several other OOPLs inasfar as that I can 
use super() or the superclass’ name to call the parent …what? – yes, the 
parent *constructor* of the class, i.e. the superclass’ (or in python, one 
of the superclass’) *constructor* from a class’ *constructor* (yes, I 
insist; see below) to initialize inherited attributes.

> Please read again the message you extracted that quote from. I already
> said I'm not claiming some other programming language's semantics should
> dictate Python's.
> 
> 
> What I'm saying is that in Python, there *already are* different
> semantics for a constructor, and they don't match the semantics of
> ‘Foo.__init__’.

Yes, *you* are saying that.
 
> In Python, a constructor for a class is a class method.

Says who, *you*?

> ‘Foo.__new__’ is a constructor. ‘Foo.__init__’ is an instance method, so
> it's not a constructor.

According to <https://docs.python.org/3/tutorial/classes.html#method-objects>, “Foo.__init__” is _not_ an instance method.  Were it an instance 
method, the following would not happen:

| >>> class Foo:
| ...     def __init__ (self):
| ...         pass
| ...
| >>> Foo.__init__.__self__
| Traceback (most recent call last):
|   File "<stdin>", line 1, in <module>
| AttributeError: 'function' object has no attribute '__self__'

Because “Instance method objects have attributes, too: m.__self__ is the 
instance object with the method m() […]”.

“Ex falso quodlibet”, “wishful thinking”, and “circular reasoning” come to 
mind here: *You* say that a constructor is a class method in Python, then 
*you* define __init__() to be an instance method, therefore __init__() 
*cannot* qualify anymore as a constructor.  So your wish is fulfilled, *far 
from reality*.

[If one would instantiate Foo, *then* the __init__() method of the instance 
would be an instance method (which is tautological):

| >>> Foo().__init__.__self__
| <__main__.Foo object at 0x7f86d73e8ef0>

]
 
> In Python, a constructor for a class makes the instance where it didn't
> already exist. ‘Foo.__new__’ is a constructor. ‘Foo.__init__’ requires
> the instance to already be constructed, so it's not a constructor.

You are also limiting the meaning of “constructor” in OOP to “create the 
instance” so that __init__() does not fit your definition of what is a 
constructor in Python in that regard as well.  But as I showed, not only 
does “constructor” not need to mean that, it can also mean much more than 
that.

So your reasoning is doubly invalid.
 
> I'm showing that Python classes *already have* constructors,

By *your* definition that you have *construed* (no pun intended) to fit your 
argument.

> and ‘Foo.__init__’ doesn't qualify because it doesn't have the semantics 
> of Python constructors.

By *your* definition.  That does not mean that your definition is correct, 
or that your reasoning is valid.

-- 
PointedEars

Twitter: @PointedEars2
Please do not cc me. / Bitte keine Kopien per E-Mail.


More information about the Python-list mailing list