1. 装饰器之functools.wraps
装饰器很好用极大地复用了代码,但是不可否认在给原函数使用装饰器后原函数的一些元数据信息比如函数名、注释、参数列表不见了,比如swagger api文档函数注释功能不可见,比如django rest_framework视图某个接口下@detail_route()再加上一个其他功能的装饰器甚至没法自动生成路由等。好在有functools.wraps解决了这个问题,wraps也是一个装饰器,它能把原函数的信息拷贝到装饰器里边的函数中,具体用法可参照如下,也建议写装饰器都这么写:
from functools import wraps
def test_dec00(func):
@wraps(func)
def wrapper(*args, **kwargs):
...
func(*args, **kwargs)
...
return wrapper
2. Django之日志处理
Django采用python内置的logging模块来处理系统日志,而一个python logging配置至少包括以下三部分:
- loggers:日志系统的入口,也就是常说的日志记录器;
- handlers:用于将日志记录发送到指定的目标位置,有关logging handlers可参见logging.handlers;
- formatters:用于控制日志记录的具体输出格式,支持的具体格式可参照logging模块支持的格式属性;
其实日志系统还包含一个组件filters
,提供更细粒度的日志过滤功能,不过实际采用中一般不多(因为上述三个组件基本上可以满足我对日志的所有需求),这里就不再赘述。
下面举例来说明一下Django配置logging日志处理的常规做法:
- 先写一个日志的专门配置文件,文件内容包括
loggers、formatters、handlers
等组件的配置,比如文件名log_conf.py
,具体内容可参照如下样式:
# log_conf.py
logging_conf = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'simple': {
'format': '%(levelname)s - %(asctime)s - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'console': {
'format':'%(levelname)s: %(asctime)s -- %(pathname)s:%(lineno)d - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
}
},
'handlers': {
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'console'
},
'fileHandler': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
'formatter': 'simple',
'filename': '/Users/vienfu/test_logs/test_error.log'
}
},
'loggers': {
'mdjango': {
'handlers': ['console', 'fileHandler'],
'level': 'INFO',
'propagate': False
}
},
'root': {
'level': 'WARNING',
'handlers': ['console', 'fileHandler'],
}
}
- 在django settings.py做日志的配置:
# settings.py
# Django Logging Settings
from log_conf import logging_conf
LOGGING = logging_conf
- 实际调用处理,在需要日志记录的函数或接口先实例化一个日志记录器:
import logging
from rest_framework.viewsets import ViewSet
logger = logging.getLogger(__name__)
# logger = logging.getLogger('mdjango') 一般这两种来实例化日志记录器,前者呢常会对应到root logger,而后则指明具体的logger
class TestViewSet(ViewSet):
def list(self, request):
...
logger.error('this is a demo logging error test')
...
如此,Django下日志配置及处理就基本上完成了。