descriptor '__init__' of 'super' object needs argument
Asked Answered
L

3

27

I'm trying my hand at making an Object-Oriented text-based game in Python, and attempting to implement my first properties and decorators. Using the chapter 5 in the book 'Python 3 Object Oriented Programming', I've tried to use the examples and concepts discussed to get the following code to set a Game-object's 'current_room' property upon instantiation:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''
    def __init__(self):
        print("Accessing the FirstRoom __init__ method.")
        super.__init__()


class SecondRoom(Room):
    ''' Just some other room.'''
    def __init__(self):
        print("Accessing the SecondRoom __init__ method.")
        super.__init__()


class Game(object):
    ''' Creates a new game.'''
    current_room = None # Class-level definition of this property.

    def __init__(self):
        print("Created a new Game object.")
        self.current_room = FirstRoom()

    @property
    def current_room(self):
        ''' Returns the current position of the actor.'''
        print("Getting the _current_room attribute for the Game object.")
        return self._current_room

    @current_room.setter   
    def set_room(self, new_room):
        ''' Sets the current_room property of the Game object.'''
        print("Setting the _current_room attribute for the Game object.")
        self._current_room = new_room

However, when I run this code, I get the following output:

>>> g = Game()
Created a new Game object.
Accessing the FirstRoom __init__ method.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/drew/Desktop/test.py", line 27, in __init__
    self.current_room = FirstRoom()
  File "/home/drew/Desktop/test.py", line 11, in __init__
    super.__init__()
TypeError: descriptor '__init__' of 'super' object needs an argument

What am I missing from my code to make this syntax work? Do I need to explicitly define a Descriptor for my 'current_room' property? [The book doesn't mention anything about Descriptors, at least not like what you would find here: Python Descriptors Demystified.]

Leif answered 27/5, 2014 at 1:52 Comment(4)
You need to actually call super.Hypodermis
possible duplicate of How to call Base Class's __init__ method from the child class?Kaye
Looks like the syntax super().__init__() and changing self.current_room = FirstRoom() to self._current_room = FirstRoom() fixed the next error. Thanks!Leif
@RSahu I don't think this question is a duplicate (of that question at least). In fact the problem of the OP was not calling super while the question you linked does call super and the errors produced are quite different.Treasury
S
111

use super().__init__() instead of super.__init__()

Safekeeping answered 7/6, 2016 at 2:56 Comment(1)
Thanks a bunch, ya a darlingAnoxemia
W
0

The super error is actually from putting the print before your call to super the following code works:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''

    def __init__(self):
        super().__init__()
        print("Accessing the FirstRoom __init__ method.")



class SecondRoom(Room):
    ''' Just some other room.'''

    def __init__(self):
        super().__init__()
        print("Accessing the SecondRoom __init__ method.")

Your need to learn how @property etc.. works.

Property python docs

From the docs, Be sure to give the additional functions the same name as the original property

class Game(object):
    ''' Creates a new game.'''
    current_room = None  # Class-level definition of this property.

def __init__(self):
    print("Created a new Game object.")
    self._current_room = FirstRoom()

@property
def current_room(self, room): 
    ''' Returns the current position of the actor.'''
    print("Getting the _current_room attribute for the Game object.")
    return self._current_room


@current_room.setter # same function name as the property.
def current_room(self, new_room):# same name  as the property
    ''' Sets the current_room property of the Game object.'''
    print("Setting the _current_room attribute for the Game object.")
    self._current_room=new_room  
Wattle answered 27/5, 2014 at 2:0 Comment(2)
Yep, using Python 3.4.0.Leif
No worries. Have a look at the docs, there are a few nice examples of how @property etc.. works.Wattle
C
0

Here the working code:

class Room(object):
    ''' An area of the game's map.'''
    def __init__(self):
        print("Accessing the Room __init__ method.")


class FirstRoom(Room):
    ''' Just some room.'''
    def __init__(self):
        print("Accessing the FirstRoom __init__ method.")
        #super.__init__()
        super(FirstRoom, self).__init__()


class SecondRoom(Room):
    ''' Just some other room.'''
    def __init__(self):
        print("Accessing the SecondRoom __init__ method.")
        super(SecondRoom, self).__init__()
        #super.__init__()


class Game(object):
    ''' Creates a new game.'''
    _current_room = None # Class-level definition of this property.

    def __init__(self):
        print("Created a new Game object.")
        self._current_room = FirstRoom()

    @property
    def current_room(self):
        ''' Returns the current position of the actor.'''
        print("Getting the _current_room attribute for the Game object.")
        return self._current_room

    @current_room.setter   
    def set_room(self, new_room):
        ''' Sets the current_room property of the Game object.'''
        print("Setting the _current_room attribute for the Game object.")
        self._current_room = new_room

and when run:

>>> g = Game()
Created a new Game object.
Accessing the FirstRoom __init__ method.
Accessing the Room __init__ method.
>>> 

Hope this may help you.

Cynthea answered 27/5, 2014 at 2:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.