10

I know that __new__ is used to create an object, while __init__ to initialize. But I'm don't understand how to use them, and I'm not sure what happens when I create an object. Does it mean that __new__ and __init__ must have the same parameters? What happens if I don't use the same parameters?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • Partly answered by [why defined '\_\_new__' and '\_\_init__' all in a class](http://stackoverflow.com/q/2017876) – Martijn Pieters Aug 03 '12 at 05:49
  • `__new__` and `__init__` do different things and have different parameters. [This question](http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init) gives a good overview. – Michael Mior Aug 03 '12 at 05:51

2 Answers2

9
  1. Yes.

  2. You will get an error.

(Technically with __new__ the first argument is the class, while with __init__ the first argument is the instance. However, it is still true that they must both be able to accept the same arguments, since, except for that first argument, the arguments passed to __init__ are the same as those passed to __new__.)

>>> class Foo(object):
...     def __new__(cls, x):
...         return super(Foo, cls).__new__(cls)
...     
...     def __init__(self, x, y):
...         pass
>>> Foo(1)
Traceback (most recent call last):
  File "<pyshell#260>", line 1, in <module>
    Foo(1)
TypeError: __init__() takes exactly 3 arguments (2 given)
>>> Foo(1, 2)
Traceback (most recent call last):
  File "<pyshell#261>", line 1, in <module>
    Foo(1, 2)
TypeError: __new__() takes exactly 2 arguments (3 given)
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 2
    And what about `*args` and `**kw` then? Also, by passing the `x` argument on to `super(..).__new__` you are triggering a DeprecationWarning, confusing the OP. – Martijn Pieters Aug 03 '12 at 06:11
  • 1
    That's why I said "must both be able to accept the same arguments". It's true that you can use `*args` and `**kwargs` to not have the exact same argument list, but that's true for any function. The important point is that the same args are *passed* to both functions, so they have to be able to accept the same things. (Thanks for noting the DeprecationWarning thing, I fixed that.) – BrenBarn Aug 03 '12 at 06:34
7

Both methods will be passed (almost) the same set of arguments, so usually they have matching signatures (the same set of parameters).

I say 'almost' there, because the __new__ method is passed the class as first argument, while the __init__ method is passed the result of the __new__ method; the freshly created instance.

In python, you can use "wildcard" parameters; the *args and **keyword (see What do *args and **kwargs mean?), which means that either __new__ or __init__ could use these to only name some of the parameters passed in.

What happens when the signatures don't match (taking into account the wildcard parameters)? You get the same result as passing arguments to any python callable whose signature does not match the arguments passed in; you get an exception.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343