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.
__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.
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.
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.
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.
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.
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__
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With