V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
conn4575
V2EX  ›  Python

Python 异常信息获取的最佳实践是什么

  •  
  •   conn4575 · 2017-12-07 07:05:55 +08:00 via Android · 4200 次点击
    这是一个创建于 2547 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 php 里面,所有异常都可以用 getMessage 获取,但是 py 里面获取异常的方式信息感觉五花八门,难道就没有统一的方式吗? 我知道的方式有:

    1. str(err),大部分情况下可以,但是有时获取到的是空的
    2. err.message, 有些异常没有该属性,可能导致新的异常
    3. err.args[0], 有些异常的第一个属性为字符串,一个个属性为异常码,另一些却相反(没错,说的就是你,socket.errer!)

    捕获一个异常后要去查文档才知道如何正确输出,心好累…

    题外话:今天捕获到一个异常,message 属性存的居然不是字符串而是一个列表,一万个 mmp !

    9 条回复    2017-12-07 09:54:21 +08:00
    lgh
        1
    lgh  
       2017-12-07 07:25:19 +08:00 via iPhone
    import traceback
    traceback.format_exc()
    zeq
        2
    zeq  
       2017-12-07 07:35:10 +08:00 via iPhone
    logging.warning(‘ something ’, exc_info=True)
    wizardmerlin
        3
    wizardmerlin  
       2017-12-07 08:48:21 +08:00   ❤️ 1
    `traceback` 推荐.
    (默认 python2)
    简单写:
    ```python
    import traceback

    try:
    raise TypeError("Oups!")
    except Exception, err:
    try:
    raise TypeError("Again !?!")
    except:
    pass

    traceback.print_exc()
    ```

    如果要拿到详细信息:
    ```python
    import traceback
    import sys

    try:
    raise TypeError("Oups!")
    except Exception, err:
    try:
    exc_info = sys.exc_info()

    # do you usefull stuff here
    # (potentially raising an exception)
    try:
    raise TypeError("Again !?!")
    except:
    pass
    # end of useful stuff


    finally:
    # Display the *original* exception
    traceback.print_exception(*exc_info)
    del exc_info
    ````

    输出结果类似如下:
    ```python
    Traceback (most recent call last):
    File "t.py", line 6, in <module>
    raise TypeError("Oups!")
    TypeError: Oups!
    ```


    python3 的话, 输出信息会少一些。
    ```python
    import traceback

    try:
    raise TypeError("Oups!")
    except Exception as err:
    try:
    raise TypeError("Again !?!")
    except:
    pass

    traceback.print_tb(err.__traceback__)
    ```

    输出大致如下:
    ```
    File "e3.py", line 4, in <module>
    raise TypeError("Oups!")
    ```

    关键是还是去看官方文档 traceback 模块:
    python2.7: https://docs.python.org/2/library/traceback.html
    python3.6: https://docs.python.org/3/library/traceback.html

    我的经验来自: [stackoverflow 链接]( https://stackoverflow.com/questions/3702675/how-to-print-the-full-traceback-without-halting-the-program)
    wizardmerlin
        4
    wizardmerlin  
       2017-12-07 08:51:00 +08:00
    晕菜了。。。回复里,缩紧全毁了。 @conn4575 同学你还是直接看一下文档吧,里面有案例。
    pabupa
        5
    pabupa  
       2017-12-07 08:54:47 +08:00 via Android
    可以试一下 vars(error),可以看到这个对象所有的属性和值。如果提示错误的话,就用 dir(error),可以看到这个对象的所有属性。

    不过最好还是去看源码里看,这个 error 是怎么抛出,怎么构造的~
    likuku
        6
    likuku  
       2017-12-07 09:01:04 +08:00
    @wizardmerlin V2EX 支持嵌入 Gist 资源,若要展示源码,最好写在那上面,再贴链接过来即可。
    siteshen
        7
    siteshen  
       2017-12-07 09:32:44 +08:00
    BaseException.args 是 python2.5 新增的属性,可以知道用户传递的是什么内容。

    print(Exception(1, 2, 3).args)
    # (1, 2, 3)

    print(Exception('xyz').args)
    # ('xyz',)

    print(Exception().args)
    # ()

    初步了解了下 PHP 的 getMessage() 类似 python 中限定了参数为字符串的异常。

    python 的异常里的内容可以是任何东西,写入的是啥,取出来的就是啥了。
    异常 catcher 并不能做什么,只能规范异常 raiser 的行为。

    如果 catcher 和 raiser 都是可控制的代码,可以自定义的异常,用这种方式规范代码。示例:

    class SomethingError(Exception):
    def __init__(self, code, message, blablabla):
    self.code = code
    self.message = message
    self.blabla = blabla

    然而即使如此,raiser 仍然可以不按“规范” raise Somthing('string', 666, []) 。
    python 语言本身没有限制用户的行为,靠用户自觉。
    ipwx
        8
    ipwx  
       2017-12-07 09:43:08 +08:00   ❤️ 3
    一般委托给 logging.exception 或者 logging.[error|warn|info|debug](..., exc_info=True)
    pigletfly
        9
    pigletfly  
       2017-12-07 09:54:21 +08:00
    sentry
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1019 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:54 · PVG 04:54 · LAX 12:54 · JFK 15:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.