r/Python 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!

0 Upvotes

22 comments sorted by

11

u/bubudumbdumb 2d ago

/s ?

9

u/ntropia64 2d ago

I am not sure this is up for debate. The __new__ method gets called before __init__

The first is a constructor that can operate on the class, the second is, well, the _init_ializer that sets the instance.

One can debate about how to use each of them, but their defined role is not really questionable.

...or I really missed the sarcasm bit.

3

u/ThatOtherBatman 2d ago

Which gets even more nuanced when you ask the “class constructor” instead of “the constructor for the class”. Because I would argue that class constructor is __new__ in the metaclass.

-6

u/declspecl 2d ago

So you would say a constructor is the thing that instantiates an object, and not initializes? What would you say about constructors in C++ and Java for example? In both languages, the object is already instantiated by the time the `class Foo { Foo() { ... } }` Foo "constructor" is executed, which would indicate they they are initializers, not instantiators

3

u/aa-b 2d ago

I would say practical usage is the most important factor, instead of getting hung up on terminology. __new__ is really a metaprogramming thing, something you only rarely need for "normal" OOP. By comparison, __init__ is equivalent to a Java constructor, so you might as well just refer to it that way to keep things simple

1

u/ntropia64 2d ago

Due to Python nature, the difference between constructor and initializer is much fuzzier than than other languages, so in theory you could do everything that the __init__ does. I used it once to do precisely that and hijack the parameters passed to the init, which made me realize you can skip it altogether. In fact, that's what happens when creating singletons.

But basically if you follow the principle of least astonishment, new and init should have those well-defined roles so another programmer (like yourself from the future) doesn't have to make too much guessing to figure things out.

-5

u/declspecl 2d ago

Fully serious. The results are 50/50 so far, so it's definitely not as cut and dry as it may seem

2

u/yrubooingmeimryte 1d ago

Because python doesn’t use the concept of “constructor” in the way other languages do.

6

u/droooze 2d ago

"Class constructor" is terminology which refers to something concrete in C++ and Java. In those languages, it

  1. is a method with the same name as the class which is invoked with the call syntax (for a class Point, this is Point());

  2. allows customisation ("initialisation") of an already-created instance;

  3. 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/Rawing7 2d ago

Where is the "That word is ambiguous, so I use more specific terminology if the difference is actually relevant to the topic" option?

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

u/allIsayislicensed 1d ago

There is also the __call__ of the metaclass to consider

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 :'(

0

u/M4mb0 1d ago

The constructor in python is the __call__ method of the meta class, which by default calls __new__ and __init__, but can be customized to do something else entirely.