8

I have been studying __new__ recently, and I've read lots of code where __new__ is used instead of __init__. Sometimes I think both work, but I don't know why the original author uses __new__.

Can someone explain why the below code uses __new__ instead of __init__? I want a reason for this example. I know the difference between __new__ and __init__, but I don't know why __new__ is used here.

Example:

    class MiniSubtest(object):
        def __new__(cls, *args, **kargs):
            self = super(MiniSubtest, cls).__new__(cls)
            ret = None
            if args is None:
                args = []
            try:
                ret = self.test(*args, **kargs)
            finally:
                if hasattr(self, "clean"):
                    self.clean()
            return ret

and I think if I use __init__, it still works, whey it used __new__?

user1334609
  • 381
  • 4
  • 12
  • 1
    Possible duplicate of [Python's use of \_\_new\_\_ and \_\_init\_\_?](https://stackoverflow.com/questions/674304/pythons-use-of-new-and-init) –  Aug 02 '17 at 01:35
  • `__init__` and `__new__` are _not_ the same. `__new__` is the method that actually creates instances of a class. It returns a new class instance. Once `__new__` has created the instance, it is passed into `__init__` via the first argument commonly named `self`. `__init__` is the method that allows you to customize the instance by initializing attributes. – Christian Dean Aug 02 '17 at 01:37
  • 1
    Yuck. Don't use a class here; use a factory function – pppery Aug 02 '17 at 01:54
  • I know that, but can you explain to me why this specific case use __new__, I think we can use __init__ too. – user1334609 Aug 02 '17 at 01:55
  • @ChamK. Yes, this is a possible duplicate. But that original post is from '09, meaning it is implying Python 2, and this question is from 2017, implying that it is Python 3. There are so many differences between the two that even in cases that haven't changed, like [`__new__`](http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Metaprogramming.html#using-init-vs-new-in-metaclasses), can we allow Python 3 & Python 2 questions to diverge in SO? Thanks! – Mike Williamson Jul 02 '18 at 15:34
  • To add on to @ppperry, here is a [tutorial of a factory function](http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Factory.html). – Mike Williamson Jul 02 '18 at 15:36
  • Side note: `if args is None: ...` is redundant here, because `*args` always creates a `tuple`. See [docs](https://docs.python.org/3/tutorial/controlflow.html#arbitrary-argument-lists). – djvg Feb 15 '22 at 08:32

2 Answers2

2

This controls the creation and return of the new instance:

  • First the instance is created.
  • The try clause catching an exception during testing the new instance.
  • Then if there is exception, it cleans the instance's garbage.
  • Then it returns None rather than the instance.

So it decides to return an instance or to discard it.

Alexander
  • 171
  • 7
0

__new__ is used to control the creation of a new instance and expects you to return it whereas __init__ only let you initialize an instance that has already been created

My guess is that self.test returns a different type of instance depending on the parameters

Michael Mior
  • 28,107
  • 9
  • 89
  • 113
Alexandre Nucera
  • 2,183
  • 2
  • 21
  • 34
  • Hi, why it need to return a different type of instance when using __new__, and, I don't see it return a different type of instances if you go to https://github.com/autotest/tp-qemu/blob/master/qemu/tests/cpuflags.py#L484 – user1334609 Aug 02 '17 at 01:42
  • since I think _\_init__ can be used here, I'll close this question if someone explained to me why it used _\_new__, and I don't think it's a duplicated question, I gave a specific example here, I hope the answer would be specific too. – user1334609 Aug 03 '17 at 04:09