Assume the following code:
class NumStorage(object):
def __new__(cls, *nargs):
name = cls.__name__
parents = cls.__bases__
kwargs = {'num%i' % pos : i for pos, i in enumerate(nargs, 1)}
if any(kwargs.values()) and len(kwargs.values()) >= 2:
end = len(kwargs.values()) + 1
kwargs['num%i' % end] = sum(kwargs.values())
self = type(name, parents, kwargs)
return self
This NumStorage
object takes in an arbitrary amount of numbers, and if there are two or more numbers and their sum adds up to something greater than 0, then it creates a new kwarg
key.
If the initialization of the instance of NumStorage can happen in __new__
then why on earth does python even need an __init__
? Another thing that's confusing me; if we do add an __init__
method to the NumStorage
class as so:
class NumStorage(object):
def __new__(cls, *nargs):
name = cls.__name__
parents = cls.__bases__
kwargs = {'num%i' % pos : i for pos, i in enumerate(nargs, 1)}
if any(kwargs.values()) and len(kwargs.values()) >= 2:
end = len(kwargs.values()) + 1
kwargs['num%i' % end] = sum(kwargs.values())
self = type(name, parents, kwargs)
return self
def __init__(self, *nargs):
print("initializing")
It never prints "initializing" even though the __init__
should be called after __new__
since __new__
returned an instance of the object, no? If not, what is it I'm getting confused with?
__init__
came first. __new__
was added primarily to... well, I'll let the documentation explain:
__new__()
is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.
__init__
was mostly good enough for the old-style class system. Even if you subclassed an "immutable" old-style class, you'd just provide the appropriate arguments to the superclass's __init__
. That doesn't cut it with subclasses of, say, tuple
.
As for __init__
not being called:
If
__new__()
returns an instance of cls , then the new instance's__init__()
method will be invoked like__init__(self[, ...])
, where self is the new instance and the remaining arguments are the same as were passed to__new__()
.If
__new__()
does not return an instance of cls , then the new instance's__init__()
method will not be invoked.
does python even need an
__init__
?
No, python doesn't need __init__
, but if there were only __new__
, every time you created a class, you'd need to figure out all the bits and pieces that go into __new__
.
It makes python much easier, and less error prone, to separate the two out.
Plus, historically __init__
precedes __new__
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.