【问题标题】:Python user-defined exceptions placement and catchingPython 用户定义的异常放置和捕获
【发布时间】:2012-11-01 18:38:03
【问题描述】:

我是 Python 新手,我不确定放置用户定义异常的最佳位置是什么,以及在哪里捕获它们。

例如,我有一个启动游戏的程序,当游戏停止时,会引发用户定义的异常(StopGame)。我应该从游戏外部捕获这个异常,因为游戏正在抛出这个异常。不过,异常是特定于游戏的,所以异常的定义应该在游戏模块(或者可能是游戏包?)中。

这是程序的简单布局:

程序结构

__main__.py
game/
    __init__.py
    game.py

__main__.py

import game

def main():
    g = game.Game()

    try:
        g.start()
    except game.StopGame:
        print '\nbye bye!'

if __name__ == '__main__':
    main()

游戏/__init__.py

from game import Game
from game import StopGame

game/game.py

class Game:

    def start(self):

        try:
            a = raw_input('do you want to play?\n')
            print 'cool'
        except (KeyboardInterrupt, EOFError):
            raise StopGame

        if a == 'no':
            raise StopGame
        else:
            print 'cool'

class StopGame(Exception):
    pass

这段代码像这样工作得很好,我只是不确定这是要走的路。令我有些失望的是,我应该使用此设置导入 game/_init_.py 中的每个异常。否则我应该捕捉到这样的异常:

except game.game.StopGame

这看起来有点讨厌。我认为最好能够从 _main_.py 中的变量 'game' 中访问模块 'game' 中的所有属性。然后我知道你可以把它放到 game/_init_.py:

from game import *

这将从game/game.py导入所有类,但我听说使用*进行导入是一种不好的做法。

那么,我的问题是,最好的方法是什么?也许我的整个设置是错误的,如果是这样,我想听听正确的设置是什么。

提前非常感谢!

顺便说一句:如果您可能想知道为什么我在游戏包中包含一个游戏模块:这个想法是该包将包含更多与游戏相关的模块,game/game.py 只是整个游戏,也许我应该将该代码放入游戏/_init_.py?

【问题讨论】:

  • 你认为StopGame应该是一个错误吗?
  • 否则我应该如何停止游戏?我可以让 Game() 返回 false 或其他东西,但是我应该在 Game() 中希望停止游戏的每个更深的层中建立这个返回机制。
  • @Blender 考虑到SystemExit 是一个例外,我认为StopGame 也是一个例外。

标签: python exception-handling


【解决方案1】:

其他地方是怎么做的?

我认为回答您的问题的最佳方法是查看实际的 Python 包并了解它是如何构建的。我以excellent python-requests package为例。

这个模块是关于发出 HTTP 请求的。你是关于玩游戏的。

基本的 HTTP 请求功能在 requests/__init__.py 文件中导入,但在别处定义。这就是你正在做的事情,但“其他地方”可能有一个更好的名字。也许game/core.py 很合适。

异常在requests/exceptions.py 文件中定义。对于一个相对较小的包来说,将所有异常集中在一个地方通常是合适的。
请注意,异常也会导入到requests/__init__.py!这使得它们更容易导入其他可能需要捕获它们的包中!

最后,没有使用from module import *。实际添加所需内容不会花费太多时间,因此您应该避免使用*


在你的情况下你能做什么?

  • 避免使用game/game.py 文件,将其命名为game/core.py 或其他名称
  • 对于小包,请将您的异常放入 game/exceptions.py 文件中
  • game/__init__.py 中,从您的包中导入通常需要的内容:主类和异常。

【讨论】:

  • 谢谢老兄,这真的很清楚!使用单独的模块来放置所有异常看起来是个好主意。我还将深入研究 requests 包。此外,重命名为 core 的建议听起来是个好主意,谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 2017-05-24
  • 2021-03-18
相关资源
最近更新 更多