2014-10-17 21 views
4

我最小的例子是使Python的`warnings.warn()`不提自己

#!/usr/bin/python3 

import warnings 

warnings.warn('Run Forest run!', stacklevel=2) 
warnings.warn('Run Forest run!') 

,它將輸出

sys:1: UserWarning: Run Forest run! 
./file.py:6: UserWarning: Run Forest run! 
    warnings.warn('Run Forest run!') 

第一行給我一點信息。第二行是完美的,給我的源文件和行號......但我想擺脫冗餘的第三行。那可能嗎?

回答

4

原來這可能讓warnings.warn()收集所有的信息,只是costumize相關信息被打印方式:

#!/usr/bin/python3 

import warnings 

def warning_on_one_line(message, category, filename, lineno, file=None, line=None): 
    return '%s:%s: %s: %s\n' % (filename, lineno, category.__name__, message) 

warnings.formatwarning = warning_on_one_line 

warnings.warn('Run Forest run!', stacklevel=2) 
warnings.warn('Run Forest run!') 

輸出:

sys:1: UserWarning: Run Forest run! 
./file.py:15: UserWarning: Run Forest run! 

來源:Python module of the week

4

您得到「冗餘」行的原因是因爲如果您不提供stacklevel參數,則默認stacklevel爲1,這基本上告訴用戶警告源於的確切代碼行,即您的警告功能請致電warnings.warn('Run Forest Run!')

如果您對其功能的使用方式不滿意,可以使用warnings.warn_explicit()函數對其進行自定義。

https://docs.python.org/3.1/library/warnings.html#available-functions

2

如果你想捕捉異常/錯誤,並希望同時看到您的自定義警告消息,並且回溯,你可能更願意使用traceback.print_exc():

import traceback 
import warnings 

def _formatwarning(msg, *a): 
    try: 
     traceback.print_exc() 
    except: 
     pass 
    return str(msg) 

warnings.formatwarning = _formatwarning 

這將使警告(」你的消息「)打印回溯,而不提及警告()本身的調用。

UPDATE:上的Python 3.6,你需要的函數簽名改爲:

def _formatwarning(message, category, filename, lineno, line='')