P
Peter Cacioppi
I've dome some reading on the difference between __new__ and __init__, and never really groked it. I just followed the advice that you should almost always use __init__.
I recently came across a task that required using __new__ and not __init__.I was a bit intimidated at first, but it was quick and easy. This simple programming exercise really cleared a lot of things up for me.
Not to be immodest, but I think something like this ought to be the canonical example for explaining when/how to override __new__.
The task? I want to make a class that behaves exactly like a tuple, except changing the constructor argument signature and adding some extra methods. An example should clarify what I needed.
etc.
Since I want the constructor to take an (almost) arbitrary number of arguments, each of which will be elements of the resulting ParetoTuple, I need tooverride __new__. I don't need to overwrite __init__, because the tuple.__new__ will populate it's data when the arguments are properly formatted.
Also, since the world of Pareto comparisons makes sense only with 2 or moregoals, I want my specialized constructor to take at least 2 arguments in anatural way.
Here is the code
class ParetoTuple(tuple) :
def __new__ (cls, obj1, obj2, *rest):
return super(ParetoTuple, cls).__new__(cls, (obj1, obj2) + rest)
# nothing special about the dominates, equivalents methods...
# no __init__ needed
I understand some people argue in favor of using a factory pattern for thissort of situation, but I disagree. I think the cognitive overhead of factories requires a more complicated task than re-signaturing the constructor method.
At any rate, hope it helps others like it helped me.
I recently came across a task that required using __new__ and not __init__.I was a bit intimidated at first, but it was quick and easy. This simple programming exercise really cleared a lot of things up for me.
Not to be immodest, but I think something like this ought to be the canonical example for explaining when/how to override __new__.
The task? I want to make a class that behaves exactly like a tuple, except changing the constructor argument signature and adding some extra methods. An example should clarify what I needed.
x = ParetoTuple(1, 2, 0)
x[1]x.dominates(ParetoTuple(1, 3, 0))2 len(x)
3 2 in x
True -1 in x
Falsex.equivalent(ParetoTuple(1, 2 + 1e-5, 0))TrueTrue
etc.
Since I want the constructor to take an (almost) arbitrary number of arguments, each of which will be elements of the resulting ParetoTuple, I need tooverride __new__. I don't need to overwrite __init__, because the tuple.__new__ will populate it's data when the arguments are properly formatted.
Also, since the world of Pareto comparisons makes sense only with 2 or moregoals, I want my specialized constructor to take at least 2 arguments in anatural way.
Here is the code
class ParetoTuple(tuple) :
def __new__ (cls, obj1, obj2, *rest):
return super(ParetoTuple, cls).__new__(cls, (obj1, obj2) + rest)
# nothing special about the dominates, equivalents methods...
# no __init__ needed
I understand some people argue in favor of using a factory pattern for thissort of situation, but I disagree. I think the cognitive overhead of factories requires a more complicated task than re-signaturing the constructor method.
At any rate, hope it helps others like it helped me.