我想在问题函数中记录异常(html解析可变页面),所以我认为最好的解决方案是这里某种装饰器,它将异常记录到文件中,具有时间,异常类型,代码和函数调用中的异常行参数,有些像:
@exception_catch(log_path='example.log')
def example(x,y):
raise Exception('123')
解决此类任务的最佳做法是什么,或者为此可能是好的python库?
答案 0 :(得分:2)
不是将路径传递给文件,而是传递记录器。这样,装饰者的用户可以决定他是否想要记录到文件或控制台,或者其他什么。记录器还将确定记录消息的格式。
您可能还需要exception
参数来定义要捕获的异常或异常类型。 (下面,exception
可以使用Exception
或Exceptions
元组。
import logging
def catch_exception(exception=Exception, logger=logging.getLogger(__name__)):
def deco(func):
def wrapper(*args, **kwargs):
try:
result = func(*args, **kwargs)
except exception as err:
logger.exception(err)
else:
return result
return wrapper
return deco
@catch_exception()
def example(x,y):
raise Exception('123')
logging.basicConfig(filename='/tmp/error.log', level=logging.DEBUG,
datefmt='%Y-%m-%d %H:%M:%S',
format='%(asctime)s %(module)s %(levelname)s: %(message)s')
example(1,2)
答案 1 :(得分:2)
你可能想做unutbu建议,因为它更灵活,最终也很简单。但是,如果您对logging
的额外细节感到不知所措,请按以下步骤操作:
def exception_catch(log_path):
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
with open(log_path, 'a') as log:
log.write('{} {} {} {} {}\n'.format(datetime.datetime.now(),
type(e), e, args, kwargs))
# This will return None on error, of course
return wrapper
return deco
当然,您可以将任何内容放入format
,包括来自上述任何范围的任何局部变量。您要求的唯一棘手的一点是“代码中的异常行”。对于2.x与3.x的详细信息略有不同(请参阅traceback
模块了解您需要知道的大部分内容),但这里有一个3.x示例,可以准确地提供您所要求的内容:
except Exception as e:
filename, line, func, text = traceback.extract_stack(limit=1)[0]
with open(log_path, 'a') as log:
log.write('time: {} type: {} line: {} args: {}\n'.format(
datetime.datetime.now(),
type(e),
line,
args))