2015-06-26 28 views
1

我正在通过Zed Shaw的LearnPythontheHardWay工作,而且我很难过。在Engine类下next_scene_name = current_scene.enter()Learn Python the Hard Way Example#43

,我发现了错误:

[Attribute Error:'NoneType' object has no attribute 'enter']

在该行。

from sys import exit 

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() 
     last_scene = self.scene_map.next_scene('finished') 

     while current_scene != last_scene: 
      next_scene_name = current_scene.enter() 
      current_scene = self.scene_map.next_scene(next_scene_name) 

     current_scene.enter() 

class EmptyScene(Scene): 

    def enter(self): 
     pass 

class FinishScene(Scene): 

    def enter(self): 
     pass 

class Map(object): 

    scenes = { 
     'empty_scene': EmptyScene(), 
     'finished': FinishScene(), 
    } 

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

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

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


a_map = Map('empty_scene') 
a_game = Engine(a_map) 
a_game.play()` 
+0

的可能重复的[Python的:属性错误 - 'NoneType' 对象没有属性 '东西'](http://stackoverflow.com/questions/8949252/python-attribute-error-nonetype-object -has-no-attribute-something) – dimo414

+0

@ dimo414我不同意,从最初的标题看来它似乎是重复的,但问题比您提出的问题更广泛。 – randomusername

回答

2

的问题是,current_scene实际上是None。这是由致电self.scene_map.next_scene致电dict.get造成的。使用dict.get的问题是,如果密钥不在字典中,那么它将仅返回None,而不是像您期望的那样引发异常。所以你的程序会继续运行,认为一切都很好,直到很久以后在代码中出现问题。

+0

如果'finished'是它搜索的下一个键,它为什么不返回?它应该返回下一个场景,对吗? –

+0

@StevenMyers不,你看错了路线。在while循环的主体中调用该函数时发生该错误。因为它搜索的关键是'current_scene.enter()'返回的值。但是请注意,一个不返回值的函数(比如以'pass'结尾的函数)将返回'None'。所以它使用'None'作为查找的关键。 – randomusername

+0

啊,我发现我做错了什么,我明白你现在在说什么。这将工作,如果我在场景的末尾做了一些事情,比如“return finished()”或“return empty_scene” –

1

这是发生,因为current_sceneNone,所以当你尝试enter()功能它给出这样的错误。

一个去了解这种方式是提供if声明:

while current_scene != last_scene: 
    if current_scene != None: 
     next_scene_name = current_scene.enter() 
     current_scene = self.scene_map.next_scene(next_scene_name) 
    else: 
     break 
1

似乎你的代码不完整。

问题的发生是因为第一次,你current_scene有一个值,它是empty_scene,然后尝试拨打current_scene.enter()得到下一个场景,但EmptySceneenter方法不返回任何东西,所以你得到None返回,那么您将current_scene更改为next_scene,即None,然后再次尝试调用enter函数,导致该问题。

你可以改变while条件 -

while current_scene != last_scene and current_scene is not None: 
    next_scene_name = current_scene.enter() 
    current_scene = self.scene_map.next_scene(next_scene_name) 

如果你想finishedempty_scene之后的下一个情景,那么你需要改变EmptyScene类返回finished而不是传递的功能。实施例 -

class EmptyScene(Scene): 

    def enter(self): 
     return 'finished' 
相关问题