Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

super() and @staticmethod interaction

Is super() not meant to be used with staticmethods?

When I try something like

class First(object):   @staticmethod   def getlist():     return ['first']  class Second(First):   @staticmethod   def getlist():     l = super(Second).getlist()     l.append('second')     return l  a = Second.getlist() print a 

I get the following error

Traceback (most recent call last):   File "asdf.py", line 13, in <module>     a = Second.getlist()   File "asdf.py", line 9, in getlist     l = super(Second).getlist() AttributeError: 'super' object has no attribute 'getlist' 

If I change the staticmethods to classmethods and pass the class instance to super(), things work fine. Am I calling super(type) incorrectly here or is there something I'm missing?

like image 802
Ben J Avatar asked Nov 06 '14 19:11

Ben J


People also ask

What is the main purpose of super () method in inheritance?

In an inherited subclass, a parent class can be referred to with the use of the super() function. The super function returns a temporary object of the superclass that allows access to all of its methods to its child class.

What is the difference between @classmethod and @staticmethod decorators?

The difference between the Class method and the static method is: A class method takes cls as the first parameter while a static method needs no specific parameters. A class method can access or modify the class state while a static method can't access or modify it.

What is the difference between @staticmethod and @classmethod in Python?

The static method does not take any specific parameter. Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class.

What is @staticmethod used for?

The @staticmethod is a built-in decorator that defines a static method in the class in Python. A static method doesn't receive any reference argument whether it is called by an instance of a class or by the class itself.


Video Answer


1 Answers

The short answer to

Am I calling super(type) incorrectly here or is there something I'm missing?

is: yes, you're calling it incorrectly... AND (indeed, because) there is something you're missing.

But don't feel bad; this is an extremely difficult subject.

The documentation notes that

If the second argument is omitted, the super object returned is unbound.

The use case for unbound super objects is extremely narrow and rare. See these articles by Michele Simionato for his discussion on super():

  • Things to Know About Python Super [1 of 3]
  • Things to Know About Python Super [2 of 3] (this one specifically covers unbound super)
  • Things to Know About Python Super [3 of 3]

Also, he argues strongly for removing unbound super from Python 3 here.

I said you were calling it "incorrectly" (though correctness is largely meaningless without context, and a toy example doesn't give much context). Because unbound super is so rare, and possibly just flat-out unjustified, as argued by Simionato, the "correct" way to use super() is to provide the second argument.

In your case, the simplest way to make your example work is

class First(object):   @staticmethod   def getlist():     return ['first']  class Second(First):   @staticmethod   def getlist():     l = super(Second, Second).getlist()  # note the 2nd argument     l.append('second')     return l  a = Second.getlist() print a 

If you think it looks funny that way, you're not wrong. But I think what most people are expecting when they see super(X) (or hoping for when they try it in their own code) is what Python gives you if you do super(X, X).

like image 156
John Y Avatar answered Sep 17 '22 06:09

John Y