Marcello Bardus
Marcello Bardus

Reputation: 395

AttributeError: 'super' object has no attribute

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?

Upvotes: 7

Views: 32559

Answers (2)

Blckknght
Blckknght

Reputation: 104852

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).

Upvotes: 14

F. Windram
F. Windram

Reputation: 93

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)

Upvotes: 1

Related Questions