-
Notifications
You must be signed in to change notification settings - Fork 2
/
9.5.py
65 lines (51 loc) · 1.72 KB
/
9.5.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# -*- coding: utf-8 -*-
"""
9.5.py
~~~~~~
定义一个属性可由用户修改的装饰器
"""
# 引入访问函数(access function)
# 使用nonlocal关键字声明变量来修改装饰器内部属性
# 把访问器函数作为函数属性附加到包装函数上
# python2.x系列没有nonlocal关键字,所以只有使用全局global关键字
from functools import wraps, partial
import logging
# 定义了一个访问器函数
def attach_wrapper(obj, func=None):
"""向函数func添加obj属性"""
if func is None:
return partial(attach_wrapper, obj)
setattr(obj, func.__name__, func)
return func
def logged(level, name=None, message=None):
"""
装饰器函数,向函数添加日志记录并允许用户自己设置日志
的等级,和希望输出的信息(以便记录)
"""
def decorate(func):
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = message if message else func.__name__
@wraps(func)
def wrapper(*args, **kwargs):
log.log(level, logmsg)
return func(*args, **kwargs)
# 设置属性 -- level
@attach_wrapper(wrapper)
def set_level(newlevel):
# nonlocal level # 使用nonlocal关键字可以让解释器在外层查找变量,从而可以修改变量
nonlocal level
level = newlevel
@attach_wrapper(wrapper)
def set_message(newmsg):
# nonlocal logmsg
nonlocal logmsg
logmsg = newmsg
return wrapper
return decorate
# 使用装饰器
@logged(logging.DEBUG)
def test(x, y):
return (x + y)
test(2, 3)
test.set_level(logging.WARNING)