问题
I understand how both __init__
and __new__
work.
I'm wondering if there is anything __init__
can do that __new__
cannot?
i.e. can use of __init__
be replaced by the following pattern:
class MySubclass(object):
def __new__(cls, *args, **kwargs):
self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
// Do __init__ stuff here
return self
I'm asking as I'd like to make this aspect of Python OO fit better in my head.
回答1:
So, the class of a class is typically type
, and when you call Class()
the __call__()
method on Class
's class handles that. I believe type.__call__()
is implemented more or less like this:
def __call__(cls, *args, **kwargs):
# should do the same thing as type.__call__
obj = cls.__new__(cls, *args, **kwargs)
if isinstance(obj, cls):
obj.__init__(*args, **kwargs)
return obj
The direct answer to your question is no, the things that __init__()
can do (change / "initialize" a specified instance) is a subset of the things that __new__()
can do (create or otherwise select whatever object it wants, do anything to that object it wants before the object is returned).
It's convenient to have both methods to use, however. The use of __init__()
is simpler (it doesn't have to create anything, it doesn't have to return anything), and I believe it is best practice to always use __init__()
unless you have a specific reason to use __new__()
.
回答2:
One possible answer from guido's post (thanks @fraca7):
For example, in the pickle module,
__new__
is used to create instances when unserializing objects. In this case, instances are created, but the__init__
method is not invoked.
Any other similar answers?
I'm accepting this answer as a 'yes' to my own question:
I'm wondering if there is anything
__init__
can do that__new__
cannot?
Yes, unlike __new__
, actions that you put in the __init__
method will not be performed during the unpickling process. __new__
cannot make this distinction.
回答3:
Well, looking for __new__ vs __init__
on google showed me this.
Long story short, __new__
returns a new object instance, while __init__
returns nothing and just initializes class members.
EDIT: To actually answer your question, you should never need to override __new__
unless you are subclassing immutable types.
来源:https://stackoverflow.com/questions/3131488/python-always-use-new-instead-of-init