AttributeError: 'super' object has no attribute

16,279

Solution 1

You're passing the wrong argument to super. If you're going to pass arguments at all, they need to be the current class and instance, not the parent class you're expecting to call. Or assuming you're using Python 3, you can skip the arguments completely and the compiler will make it work for you anyway. Calling super with one argument is allowed, but it returns an "unbound super object" which is almost never useful.

Change your calls to use one of these styles:

class Child(Parent):
   def __init__(self):
      super().__init__()   # no arguments is almost always best in Python 3

   def do_something(self, some_parameter, next_parameter):
      super(Child, self).do_something(some_parameter, next_parameter) # name the current class
      return some_parameter + next_parameter 

I'd also note that your type checks in Parent.do_something are rather awkward. Rather than type(some_parameter) is not int, use isinstance(some_parameter, int) (unless you deliberately want to exclude subtypes).

Solution 2

You have a few issues here. Firstly there was an indentation error for the parent do_something definition. This meant that it was defined as a function in and of itself, rather than being a method of the class Parent.

Secondly, class methods should usually have self as their first parameter, as when they are called, the object that they refer to is passed as the first variable.

Thirdly, when you call super() you do not need to specify what the super is, as that is inherent in the class definition for Child.

Below is a fixed version of your code which should perform as you expect.

class Parent:
    def __init__(self):
        pass
    def do_something(self, some_parameter, next_parameter):
        if type(some_parameter) is not int:
            raise AttributeError("Some message")
        if type(next_parameter) is not int:
            raise AttributeError("Some message")
class Child(Parent):
    def __init__(self):
        super(Parent).__init__()
    def do_something(self, some_parameter, next_parameter):
        super().do_something(some_parameter, next_parameter)
        return some_parameter + next_parameter

test = Child()
test.do_something(2, 2)
Share:
16,279

Related videos on Youtube

Marcello Bardus
Author by

Marcello Bardus

Updated on June 04, 2022

Comments

  • Marcello Bardus
    Marcello Bardus about 2 years

    I wrote the following code. When I try to run it as at the end of the file I get this stacktrace:

    AttributeError: 'super' object has no attribute do_something
    


    class Parent:
        def __init__(self):
            pass
    
        def do_something(self, some_parameter, next_parameter):
            if type(some_parameter) is not int:
                raise AttributeError("Some message")
            if type(next_parameter) is not int:
                raise AttributeError("Some message")
    
    
    class Child(Parent):
        def __init__(self):
            super(Parent).__init__()
    
        def do_something(self, some_parameter, next_parameter):
            super(Parent).do_something(some_parameter, next_parameter)
            return some_parameter + next_parameter
    
    
    object = Child()
    object.do_something(2, 2)
    

    How should I solve this and where did I the mistake in this simply inheritance sample?

    • Mr Alihoseiny
      Mr Alihoseiny almost 6 years
      I think you forgot the self parameter in do_something method in parent class.
    • Aran-Fey
      Aran-Fey almost 6 years
      None of your methods have a self parameter, and super(Parent) should be super(), and why on earth are you raising AttributeError if your type checks fail?
    • Marcello Bardus
      Marcello Bardus almost 6 years
      You're right I forgot to write this parameter but only in this sample in my code I did not forget about self parameter and it's still getting the same error. But thanks the same.
    • Aran-Fey
      Aran-Fey almost 6 years
      None of your __init__ methods have self parameters.
    • Marcello Bardus
      Marcello Bardus almost 6 years
      I just added self param in the method definition and it's still not the reason.
  • Marcello Bardus
    Marcello Bardus almost 6 years
    Thanks that's it :)
  • F. Windram
    F. Windram almost 6 years
    Just as an addition, it looks like the first def __init__(): was doubly indented which may have caused the initial problem.
  • Marcello Bardus
    Marcello Bardus almost 6 years
    Great thanks for the answer. Is it better to use only super() or call it with the args SubClassName and self? What is more recommended?
  • Blckknght
    Blckknght almost 6 years
    If you only need to support Python 3, using the no-argument for is almost always best, because it's simpler and you don't need to change it if you rename the class. The two argument form is the only one that works in Python 2, so use it if you need backwards compatibility (this is getting much less important as Python 2 approaches its end of life).