Python 用户定义的异常放置和捕获

标签 python exception-handling

我是 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

游戏/游戏.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 只是整个游戏,也许我应该把代码放到 game/_init_.py 中?

最佳答案

其他地方是怎么做到的?

我认为回答您的问题的最佳方法是查看实际的 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 中,从您的包中导入通常需要的内容:主要类和异常。

关于Python 用户定义的异常放置和捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13183441/

相关文章:

python - 使用 Python 和 BeautifulSoup 为 Yahoo 和 Bing 生成多个页面的 URL

python - 如何将字符串拆分为两个单词的不同片段,其中第二个片段的第一个单词重复第一个片段的最后一个单词

c++ - 在 C++ 中,是否可以强制用户捕获异常?

c++ - GCC comp_except_specs 和异常处理/解析

c++ - 在 C++ 中, “throw” 和 “throw ex” 之间有区别吗?

python - 用 libclang 解析;无法解析某些标记(Windows 中的 Python)

Python3 ginput 警告 : Using default event loop

C# try-catch-else

Python Selenium - 尝试按类名查找元素时出错

sql - 如何在过程执行期间跟踪异常错误消息