r/Python • u/declspecl • 2d ago
Discussion Constructors: __init__, __new__, both, neither?
Hi all, I'm doing some research on what programmers believe is the class constructor in Python. I made a poll here: https://strawpoll.com/05ZdzVzdmn6 and would appreciate all responses, thanks!
6
u/droooze 2d ago
"Class constructor" is terminology which refers to something concrete in C++ and Java. In those languages, it
is a method with the same name as the class which is invoked with the call syntax (for a
class Point
, this isPoint()
);allows customisation ("initialisation") of an already-created instance;
must not return anything.
__init__
does (2) and (3). (1) is enabled by the metaclass's __call__
method, but unlike the other languages it must also handle allocation (instance creation, normally by calling a class's __new__
method internally), and the returned result must be a fully-initialised object.
Nothing in Python corresponds to "the class constructor" in other languages; __init__
comes the closest, but is also optional, as you can do class construction in metaclass __call__
or class __new__
as well. However, if you don't do class construction in __init__
, Python forces you to handle allocation (instance creation) and instance customisation together.
2
u/Spill_the_Tea 2d ago
Did you get corrected in an interview?
3
u/ToddBradley 1d ago
It does feel like "I'm in a pissing contest with someone about this, and now I'm going to take a poll to see who's right".
2
u/bubudumbdumb 2d ago
Not a lawyer but there is official doc on this
https://docs.python.org/3/reference/datamodel.html#object.__init__
Both new() and init() work together in constructing objects.
Neither method is referred to as a constructor but the expression calling it is called a class constructor expression while when creating a new class is called object constructor expression.
Is this confusing? Yes
2
2
u/ToddBradley 1d ago
I came to Python by way of Java and C#, and have been using it weekly for the past several years. I have never once used __new__
, only __init__
. And of code I've maintained that was written by others on a few different projects, I haven't seen a single person use __new__
.
So I voted __init__
, because for the colloquial use of the word "constructor", that's what it seems like the vast majority of people use.
1
u/yrubooingmeimryte 1d ago
But you can create classes in python without ever writing an init method. So if they are optional, can they really be considered the constructor of the object?
1
u/ToddBradley 1d ago
Beats me. Every language I've used in the past 20 years that has constructors also makes them optional - Java, C#, and Python. C++ didn't have the concept of a default constructor when I used it in the 90s, but maybe that's changed since then.
2
u/pbecotte 2d ago
Considering the python object model, "constructor" would be very ambiguous defined. I could see a legitimate argument for all four answers. Unless you're just trying to get an idea of what percentage of your respondents actually understand the object model?
1
u/declspecl 2d ago
Exactly, I think a case could be made for each one. I'm really just trying to see what the distribution is of what people thing of when they think "constructor"
Though personally I would probably vote for `__init__` , since constructors in other languages tend to be initializers and not the actual allocating function. Although Python is tricky because of when fields are defined and initialized. But in the same breath, "fields" don't exist in C++ like they do in Python or Java, and I'm positive almost nobody would argue that `malloc` is a constructor. So definitely an interesting discussion imo!
2
u/pbecotte 2d ago
If we are having a philosophical one, I think I'd go with "both" since you generally need the combination to actually build a useful object- and don't understand the object model of any other language well enough to actually know the difference lol.
1
u/onlyonequickquestion 2d ago
I must be dumb cuz I picked something that only two people outta twenty voted for :'(
11
u/bubudumbdumb 2d ago
/s ?