python481516
python481516

Reputation: 84

Why can't you omit the arguments to super if you add *args in __init__ definition?

class MyClass:
    def __init__(*args):
        print(super())

MyClass()

Why does this code raise RuntimeError: super(): no arguments? This is in Python 3.7.4.

Upvotes: 0

Views: 630

Answers (2)

jonrsharpe
jonrsharpe

Reputation: 122115

Per PEP 3135, which introduced "new super" (emphasis mine):

The new syntax:

super()

is equivalent to:

super(__class__, <firstarg>)

where __class__ is the class that the method was defined in, and <firstarg> is the first parameter of the method (normally self for instance methods, and cls for class methods).

There must be a specific first parameter for this to work (although it doesn't necessarily have to be called self or cls), it won't use e.g. args[0].


As to why it needs to be a specific parameter, that's due to the implementation; per the comment it uses the "first local variable on the stack". If co->co_argcount == 0, as it is when you only specify *args, you get the no arguments error. This behaviour may not be the same in other implementations than CPython.


Related

Upvotes: 4

Александр
Александр

Reputation: 289

Because the first argument of __init__ should be reference to a class instance. If you pass first *args instead some position argument, first argument becomes a tuple:

class MyClass:
    def __init__(self, *args):
        print(self)
        print(args)
        print(super())

MyClass(1,2)

this code will show to the result like this:

<__main__.MyClass object at 0x7f84228ce3c8>  
(1, 2)  
<super: <class 'MyClass'>, <MyClass object>>

Where <__main__.MyClass object at 0x7f84228ce3c8> is reference to the class instance. You can't trick the interpreter by passing first *args(tuple) or **kwargs(dict of named args) instead, because first argument can be just position argument

Upvotes: 0

Related Questions