Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any reason to choose __new__ over __init__ when defining a metaclass?

I've always set up metaclasses something like this:

class SomeMetaClass(type):
    def __new__(cls, name, bases, dict):
        #do stuff here

But I just came across a metaclass that was defined like this:

class SomeMetaClass(type):
    def __init__(self, name, bases, dict):
        #do stuff here

Is there any reason to prefer one over the other?

Update: Bear in mind that I'm asking about using __new__ and __init__ in a metaclass. I already understand the difference between them in another class. But in a metaclass, I can't use __new__ to implement caching because __new__ is only called upon class creation in a metaclass.

like image 806
Jason Baker Avatar asked Dec 03 '09 15:12

Jason Baker


People also ask

What is difference between INIT and new?

__new__ is the first step of instance creation. It's called first and is responsible for returning a new instance of your class. In contrast, __init__ doesn't return anything; it's only responsible for initializing the instance after it's been created.

Is __ init __ necessary in Python?

No, it is not necessary but it helps in so many ways. people from Java or OOPS background understand better. For every class instance, there is an object chaining that needs to complete when we instantiate any class by creating an object.

Why do we use __ init __?

The __init__ method is the Python equivalent of the C++ constructor in an object-oriented approach. The __init__ function is called every time an object is created from a class. The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.

What is the need of def __ init __( self Param?

class Point: def __init__(self, x, y): self._x = x self._y = y. The __init__ method gets called after memory for the object is allocated: x = Point(1,2) It is important to use the self parameter inside an object's method if you want to persist the value with the object.


2 Answers

If you want to alter the attributes dict before the class is created, or change the bases tuple, you have to use __new__. By the time __init__ sees the arguments, the class object already exists. Also, you have to use __new__ if you want to return something other than a newly created class of the type in question.

On the other hand, by the time __init__ runs, the class does exist. Thus, you can do things like give a reference to the just-created class to one of its member objects.

Edit: changed wording to make it more clear that by "object", I mean class-object.

like image 105
Matt Anderson Avatar answered Sep 18 '22 17:09

Matt Anderson


You can see the full writeup in the official docs, but basically, __new__ is called before the new object is created (for the purpose of creating it) and __init__ is called after the new object is created (for the purpose of initializing it).

Using __new__ allows tricks like object caching (always returning the same object for the same arguments rather than creating new ones) or producing objects of a different class than requested (sometimes used to return more-specific subclasses of the requested class). Generally, unless you're doing something pretty odd, __new__ is of limited utility. If you don't need to invoke such trickery, stick with __init__.

like image 38
Ben Blank Avatar answered Sep 21 '22 17:09

Ben Blank