Reputation: 717
Continuing the discussion from this question: Dynamically adding methods with or without metaclass, when doing the dynamic injetion, what is the difference and benefits/issues of doing it in the __new__
method vs. the __init__
method?
In the referenced question the new method is added by using setattr
. If you do this in the__new__
method, you need to modify the dict
parameter. Using the same example, it would be something like this:
class Meta(type)
def __new__(cls, clsname, bases, dct):
def my_method(self, x):
return x in self.letters
dct[my_method.__name__] = my_method
return super(Meta, cls).__new__(cls, clsname, bases, dct)
Upvotes: 7
Views: 6438
Reputation: 77912
If you do this in the new method, you need to modify the dict parameter
Well, not necessarily, you can as well use setattr
after you created the new class object, ie:
class Meta(type)
def __new__(cls, clsname, bases, dct):
def my_method(self, x):
return x in self.letters
newclass = super(Meta, cls).__new__(cls, clsname, bases, dct)
setattr(newclass, my_method.__name__, my_method)
return newclass
So basically, in Meta.__init__
you can only modify the already instanciated class object, while in Meta.__new__
you can inspect and modify the parents and namespace before creating the class and modify the created class afterward.
So what's the point of using __init__
at all ? Well sometimes you don't need all the power __new__
gives you only want to modify the newly created class, and then __init__
saves you the extra boilerplate of creating the class.
Upvotes: 13