【问题标题】:Function does not return any value if called in a class如果在类中调用函数不返回任何值
【发布时间】:2015-06-01 17:51:47
【问题描述】:

我正在尝试根据我找到的教程制作我的 Zork & Adventures 版本here

本教程使用一个引擎类,该类从地图类中选择接下来必须出现的场景等等。 为了选择下一个场景,引擎获取一个函数的返回值并选择要播放的场景。

从系统导入退出 从随机导入randint

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)

        # be sure to print out the last scene
        current_scene.enter()

class Death(Scene):

    quips = [
        "You died.  You kinda suck at this.",
         "Your mom would be proud...if she were smarter.",
         "Such a luser.",
         "I have a small puppy that's better at this."
    ]

    def enter(self):
        print Death.quips[randint(0, len(self.quips)-1)]
        exit(1)

class CentralCorridor(Scene):

    def enter(self):
        print "you entered"

        action = raw_input("> ")

        if action == "1":
            return 'death'

        elif action == "2":
            return 'death'

        else:
            print "DOES NOT COMPUTE!"
            return 'central_corridor'

class Finished(Scene):

    def enter(self):
        print "You won! Good job."
        return 'finished'

class Map(object):

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

    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('central_corridor')
a_game = Engine(a_map)
a_game.play()

我讨厌这段代码的地方在于,如果用户拼错了action,课程会重新开始。我不想再次打印所有内容,我只想提示用户raw_input

我认为这就足够了:

class Actions(object):

    # Asks a command to the user
    def action(self, actions):
        self.actions = actions

        command = raw_input('> ')

        if command in self.actions.keys():
            return self.actions[command]

        elif command == 'HELP':
            print 'The available actions are:'
            for value in self.actions.keys():
                print ' * ', value
            self.action(self.actions)

        else:
            print 'Repeat please:'
            self.action(self.actions)

cmd = Actions()

使用这个模块,用户可以数字化他想要的东西,直到他数字化的动作是字典中的动作之一。

当我单独运行这个模块时,它可以工作。如果我输入print 而不是return,它将打印该值。 但是,如果我导入此模块,一切都会正常工作,但返回值:

class CentralCorridor(Scene):

    actions = {
        'quit': 'death' # I need that cmd.action() returns 'death'
    }

    def enter(self):
        print "you entered"

        cmd.action(CentralCorridor.actions)

python 控制台返回:

Traceback (most recent call last):
  File "main.py", line 77, in <module>
    a_game.play()
  File "main.py", line 24, in play
    next_scene_name = current_scene.enter()
AttributeError: 'NoneType' object has no attribute 'enter'

看起来它只适用于这段代码(我不想使用的代码): 动作 = raw_input("> ")

if action == "1":
    return 'death'

elif action == "2":
    return 'death'

else:
    print "DOES NOT COMPUTE!"
    return 'central_corridor'

您能否解释一下我做错了什么以及为什么它不起作用或如何使它起作用?

【问题讨论】:

  • 好像变量current_scene设置为None

标签: python function class methods


【解决方案1】:

这是因为你没有从 Actions 类中的递归调用中返回值,它应该是:

class Actions(object):

    # Asks a command to the user
    def action(self, actions):
        self.actions = actions

        command = raw_input('> ')

        if command in self.actions.keys():
            return self.actions[command]

        elif command == 'HELP':
            print 'The available actions are:'
            for value in self.actions.keys():
                print ' * ', value
            return self.action(self.actions) # return recursive call

        else:
            print 'Repeat please:'
            return self.action(self.actions) # return here too

cmd = Actions()

你也忘了在 CorridorScene 中返回 cmd.action 调用:

class CentralCorridor(Scene):

    actions = {
        'quit': 'death' # I need that cmd.action() returns 'death'
    }

    def enter(self):
        print "you entered"

        return cmd.action(CentralCorridor.actions) # return here too

【讨论】:

  • 还是不行!回溯(最后一次调用):文件“main.py”,第 77 行,在 rooms_of_madness.play() 文件“main.py”,第 24 行,播放中 next_scene_name = current_scene.enter() AttributeError: 'NoneType ' 对象没有属性 'enter'
  • @dcdeiv 那么您的 current_scene 在 play 方法中设置为 None 时也会出错。您将需要尝试调试该代码。
  • 代码末尾不是设置为a_map = Map('central_corridor')吗?
  • @dcdeiv 您在调用 cmd.actions() 时也忘记了返回。您需要在 CentralCorridor 类中返回 cmd.action(CentralCorridor.actions) 调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
相关资源
最近更新 更多