-3

According to the docs,

Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
...

If __new__ does not return an instance of cls, then the new instance’s __init__() method will not be invoked.

The simplest implementation of __new__:

class MyClass:
    def __new__(cls):
        RetVal = super(currentclass, cls).__new__(cls)
        return RetVal

How exactly does super(currentclass, cls).__new__(cls[, ...]) return an object of type cls?

That statement calls object.__new__(cls) where cls is MyClass.

So how would class object know how to create the type MyClass?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Bob
  • 4,576
  • 7
  • 39
  • 107
  • 1
    You *told* it what type the returned object should have. That's what the `cls` parameter is for. – user2357112 Jul 29 '16 at 19:11
  • @user2357112 I don't get your answer. The return type it expects is `cls`. How does `super(currentclass, cls).__new__(cls)` return a `cls`? Are you saying it implicitly casts it? – Bob Jul 29 '16 at 19:13
  • 1
    `object.__new__` looks at the `cls` parameter you passed it and says, "Gee, I guess Adrian wants an object of type `cls`. I should make one of those." – user2357112 Jul 29 '16 at 19:14
  • @user2357112 Ok. What about the `super(class1, class2)` statement; what's the logic there? It gets the base class that's common to both classes or what? – Bob Jul 29 '16 at 19:18
  • 1
    [Didn't I just answer that for you a few hours ago?](http://stackoverflow.com/questions/38661438/python-super-two-argument-version-in-context-of-new) – user2357112 Jul 29 '16 at 19:21
  • @user2357112 Is this correct? ["To begin with super() in itself is simply shorthand for super(A, B), where A is the class wherein the code occurs, and B is the first argument to the function in which the code occurs; so in your particular case](http://stackoverflow.com/a/9092004/4784683) If that's correct, seems pointless; doesn't Python know in which function the code is? – Bob Jul 29 '16 at 19:21
  • Does it matter how Python does this? `object.__new__` returns a new C structure that links to the class object. It is all done in C. Is that what you are looking for? – Martijn Pieters Jul 29 '16 at 19:24
  • @MartijnPieters the `object.__new__` answer absolutely makes sense and yes that's what I'm looking for. What I'd also like to know is the syntax behind `super`. In the doc, says in `super(class1, class2)` that `issubclass(class2, class1)` must be true. OK. But then how does `super` use BOTH classes to return whatever it returns? – Bob Jul 29 '16 at 19:29
  • 3
    @Adrian: that's an entirely different question; I have written [several answers about `super()` that cover this](https://stackoverflow.com/search?q=user%3A100297+super+self+class+type) and more. – Martijn Pieters Jul 29 '16 at 19:30
  • @Adrian: it matters what *class* the function was original defined on, vis-a-vis the MRO. The 'magic' `__class__` closure defines this. Also see [Why is Python 3.x's super() magic?](https://stackoverflow.com/q/19608134) – Martijn Pieters Jul 29 '16 at 19:43

2 Answers2

2

super(MyClass, cls).__new__(cls) first searches the MRO (method resolution order) of the cls object (skipping past MyClass in that sequence), until it finds an object with a __new__ attribute.

In your case, that is object.__new__:

>>> class MyClass:
...     def __new__(cls):
...         RetVal = super(MyClass, cls).__new__(cls)
...         return RetVal
...
>>> MyClass.__mro__
(<class '__main__.MyClass'>, <class 'object'>)
>>> hasattr(MyClass.__mro__[1], '__new__')
True

but if you subclassed MyClass and mixed in another class into the MRO with a __new__ method then it could be another method.

object.__new__ is implemented in C, see the object_new() function; it contains a hook for abstract base classes to make sure you are not trying to instantiate an abstract class, then delegates to the tp_alloc slot, which usually will be set to PyType_GenericAlloc, which adds a new PyObject struct to the heap. It is that struct that represents the instance to the interpreter.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Shouldn't `currentclass` be replaced by `MyClass`? – Bob Jul 30 '16 at 19:56
  • 1
    @Adrian: I was following your example in your question. Yes, a correct invocation would use `MyClass`. – Martijn Pieters Jul 30 '16 at 22:06
  • Ok. So then can you point to **documentation** that explains what `super(MyClass, cls)` **means** i.e. how does `super` act on its two arguments to return . . . whatever it returns. [Python.org](https://docs.python.org/3/library/functions.html#super) does NOT state this info. – Bob Jul 30 '16 at 22:10
  • 1
    @Adrian: then I don't know what to point you to. That documentation is spot on. – Martijn Pieters Jul 30 '16 at 22:11
  • Where in that link is my question answered: how do the two arguments to super influence/affect what is returned? It just says that the second argument must be a subclass of the first argument. – Bob Jul 30 '16 at 22:13
  • 1
    @Adrian: `super(type)` returns an unbound proxy, `super(type, object-or-type)` produces bound attributes. The proxy uses attribute access to search the MRO in the same way `getattr()` does, skipping `type` in that order. – Martijn Pieters Jul 30 '16 at 22:17
  • 1
    @Adrian: the documentation makes assumptions about you knowing what MRO is, and what binding does. Also see [How can I use super() with one argument in python](https://stackoverflow.com/q/30190185) where I dive into what binding means and how the one-argument from can be bound after-the-fact. – Martijn Pieters Jul 30 '16 at 22:19
  • what does bound mean in this case? In my example: super(MyClass, cls) what is bound to what and what does "bound" mean? – Bob Jul 30 '16 at 22:19
  • ok I'll read about mro and binding. Thanks for taking the time – Bob Jul 30 '16 at 22:19
  • @Adrian: also see the [descriptor protocol](https://docs.python.org/3/howto/descriptor.html); binding is what happens when you look up attributes on an instance or class that implement that protocol. It is how methods acquire the `self` argument and how `property` objects end up calling a function when accessed. – Martijn Pieters Jul 30 '16 at 22:21
0

Few things, first of all you need to write explicit inheritance from object like this:

class MyClass(object):

You should read about old classes and new classes on python(only on python 2, in python 3 it does not matter)

For your question, I think you missed the point or syntax of super() functions. Again, small change to your code:

RetVal = super(MyClass, cls).__new__(cls)

In this way you reference to the parent-class by using super(MyClass, cls) and calling a method from this parent-class new(of course you can use any other method)

edit After reading your comments, I'll just add that super() doesn't have to take any arguments in Python 3 so maybe it's more trivial for you. Highly recommended to read more about the super() here

Community
  • 1
  • 1
Or Duan
  • 13,142
  • 6
  • 60
  • 65