Woomfy Woomfy - 8 days ago 5
Python Question

How to debug an AttributeError in Python?

So I have been working out of Zed Shaw's Learn Python The Hard Way and have had some pretty good success until Exercise 43 which walks you through creating a very simple text based game using Object-Oriented Programming principles. I have repeatedly been getting the an attribute error, more specifially:

File "PracticeGame.py", line 206, in <module>
a_game.play()
File "PracticeGame.py", line 20, in play
next_scene_name = current_scene.enter()
AttributeError: 'NoneType' object has no attribute 'enter'


I have seen multiple posts regarding this error, but none of the answers have really explained this problem in ways I can understand, nor have the solutions provided worked for me. Following are the lines from the code including line 20:

class Scene(object):

def enter(self):
print "This scene is not yet configured. Subclass it and implement enter()."
exit(1)

class Engine(object):

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

def play(self):
current_scene = self.scene_map.opening_scene()

while True:
print "\n-------"
next_scene_name = current_scene.enter() #this is line 20
current_scene = self.scene_map.next_scene(next_scene_name)
return current_scene


This is the end of the code including line 206

a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play() #line 206


Map is defined as:

class Map(object):

scenes = {
'central_cooridor': CentralCorridor(),
'laser_weapon_armory': LaserWeaponArmory(),
'the_bridge': TheBridge(),
'escape_pod': EscapePod(),
'death': Death()
}

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

def next_scene(self, scene_name):
return Map.scenes.get(scene_name)

def opening_scene(self):
return self.next_scene(self.start_scene)


I understand from different posts that this error message means that some part of line 20 is not defined, but I'm lost as to what isn't defined and why it is occurring. I am new to Python.

Answer

Your error says 'NoneType' object has no attribute 'enter'. which means that you have some object of type NoneType and you are trying to access attribute named enter. Now, Python has exatly one obect of type NoneType: None. Thus, the compiler is trying to tell you that you are doing X.enter and X is None.

Now lets look at the context. The context is: File "PracticeGame.py", line 20, in play next_scene_name = current_scene.enter() From the first paragraph, the error is that current_scene is None. Now you want to trace backwards thru the program and find out where did current_scene come from. In your case, it came from Map.scenes.get(scene_name), where scene_name = 'central_corridor'. map.get returns None when key is not found, so this must be your problem. You look closer and find out that you mis-spelled scene name as 'central_cooridor' in your map definition.

Comments