Issue: TypeError: __init__() missing 1 required positional argument: 'room'

I get TypeError: init() missing 1 required positional argument: ‘room’ when I run this code (which is a very cut down version of the original code to show the root problem)

from sys import exit
from textwrap import dedent

# Room superclass. All individual rooms are subclasses of Room()
class Room(object):
    def __init__(self, room):
        self.room = room
    def thing(self):
        pass

class One(Room):
    def __init__(self, room):
        self.room = room

    # Function for first time entry
    def enter(self, room):
        print("Entering room One.")
        exit(0)

class Engine(object):

    scenes = {'ONE': One()}

    def __init__(self, room):
        self.room = room

    def play(self):
        final_room = "exit"

        # Loop until you hit "exit"
        while self.room.lower() != final_room:
            next_room = Engine.scenes[self.room.upper()]
            next_room_key = next_room.enter(self.room)

start_room = Engine('One')
start_room.play()

I already solved the problem (after banging my head against a wall for a few hours). What’s not clear to me is why the presence of init statements in the Room() superclass and One() subclass forces me to change the dictionary value from

scenes = {'ONE': One()} 

to

scenes = {'ONE': One(Room)} 

I get that I need to pass a parameter through the instance of One(Room) I created. What I’m not getting is why I need to put the superclass name in there to make it work.

What do you mean by “pass through the instance”?

You certainly don’t need to pass the name of the parent class for initialization. You can pass anything, but you do need to pass something because One. __init__ takes a parameter.

1 Like

Sorry typo. “Through” should have been “to”.

The issue is if I use anything other than One(Room) the code breaks. If I use, for example, One(Thing) I’ll get a NameError: name “Thing” is not defined. You can try it yourself with that code. Put anything other than “One(Room)” as the value in the scenes dictionary in the Engine() class and it breaks. I’d like to know why because I’m not understanding its necessity.

Python isn’t type safe so you don’t have to bother with the inheritance is you’re not putting common code into the Room class. You could easily just make a flat OOP system that didn’t bother with that, and then later if you see you have common code in all of your rooms, “pulll it up” into a base class they all reference.

Well of course the thing you pass must be defined (like with every other function parameter). Try passing literals like 42 or "foo" or [1, 2, 3].

1 Like
A free service run by Zed A. Shaw for learncodethehardway.org.