Python Classes in 2 Files [Learn Python the Hard Way]
Question: Hey guys, I'm currently completing Zed Shaw's ["Learn Python the Hard
Way"](http://learnpythonthehardway.org/static/LearnPythonTheHardWay.pdf) and
I've been struggling with Exercise 43, which instructs the learner to make a
game. For simplicity, I am attempting to rewrite the previous exercise that
has a class `Game` and some functions:  
`__init__`, `play`, `death`, and four more for each "room" in the game.

I was able to copy and modify the code for various conditions, but I wanted to
try to split the code in to two files: one file containing a class
`PrincessRoom` to be the sole room for the game, and the other containing the
bulk of the old code `play` and `death`.

From `ex43.py`

    
    
    from sys import exit
    from random import randint
    from ex43princess import PrincessRoom
    
    class Game(object):
    
        def __init__(self, start):
            self.quips = [
                "You died. You suck.",
                "Hey, you died. Look at that.",
                "You lose. I win. End.",
            ]
            self.start = start
    
        def play(self):
            next = self.start
    
            while True:
                print "\n--------"
                room = getattr(self, next)
                next = room()
    
        def death(self):
            print self.quips[randint(0, len(self.quips)-1)]
            exit(1)
    
    a_game = Game("princess")
    a_game.play()
    

From `ex43princess.py`

    
    
    class PrincessRoom(object):
    
        def __init__(self):
            pass
    
        def princess(self):
            print "text here"
    
            raw_input("> ")
    
            if raw_input == 1:
                return 'eat_it'
            else:
                return 'death'
    
        def eat_it(self):
            print "text here"
    

When I run the code, here's the error I get:

    
    
    Traceback (most recent call last):
      File "ex43-2.py", line 29, in <module>
        a_game.play()
      File "ex43-2.py", line 21, in play
        room = getattr(self, next)
    AttributeError: 'Game' object has no attribute 'princess'``
    

Now I'm not too solid on why the original code had `a_game` initialized with
`a_game = Game("princess")` but I'm pretty sure it's directly related to why
it has me use `room = getattr(self, next)`. But this is where my understanding
falters.

If memory serves, it would appear that `Game` object isn't inheriting properly
from ex43princess.py... right?

If any one could help me understand what is happening here I would be much
appreciative.

Thanks! Josh


Answer: _Note: I'm not familiar with the book and hence with the context of the
question, so my answer refers to the displayed code only_

The problem here isn't splitting the code to two files. As far as I can see,
the `PrincessRoom` class in its own file presents no real problem.

`Game` can't find the `princess` method, and it doesn't have one. Perhaps it
should've inherited from `PrincessRoom`?

That said, I'm not sure that it makes sense logically to inherit a class named
`Game` from a class named `PrincessRoom`. A better approach IMHO would be
_aggregation_ \- i.e. keep a collection of rooms as an instance variable of
`Game` and access them through it. Inheritance should be really reserved to
_is-a_ relations. You should ask yourself, whether "Game is-a PrincessRoom"
makes sense. It probably doesn't. What does make sense is "Game has-a
PrincessRoom", and _has-a_ is represented by aggregation in OOP.

