2015-06-26 27 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' 
相關問題