使用 Python 中的Decorator完成以下功能, 代码均是在Python 3.6下编写:
- 记录函数调用时参数的 Log 工具
- 函数调用计数器.
分别使用 函数装饰器 和 类装饰器 完成.
log 工具
创建一个 函数装饰器, 该装饰器的作用是输出其所wrap函数的函数名与参数, 很多时候可以作为日志工具, 追踪代码执行轨迹.
创建函数装饰器
def log_func(func):
def _wrapper(*args, **kwargs):
print('Execute {} with args: {}, {}'.format(func.__name__, args, kwargs))
return func(*args, **kwargs)
return _wrapper
创建函数并使用装饰器
@log_func
def add(x, y, z):
return x + y + z
在控制台调用函数, 检查控制台输出
if __name__ == "__main__":
a = add(2,3, z=5)
print(a)
输出结果为
Execute add() with args: (2, 3), {'z': 5}
10
函数调用技术器
这是Python官方列出的装饰器的一种用法, 见页面PythonDecoratorLibrary#Counting_function_calls.
创建类装饰器, 该装饰器负责将wrap的函数, 存储在类的静态列表里, 并暴露两个静态方法, 用于显示单个函数或所有函数的调用次数统计情况.
创建类装饰器
class countcalls(object):
"Decorator that keeps track of the number of times a function is called."
__instances = {}
def __init__(self, f):
self.__f = f
self.__numcalls = 0
countcalls.__instances[f] = self
def __call__(self, *args, **kwargs):
self.__numcalls += 1
return self.__f(*args, **kwargs)
@staticmethod
def count(f):
"Return the number of times the function f was called."
return countcalls.__instances[f].__numcalls
@staticmethod
def counts():
"Return a dict of {function: # of calls} for all registered functions."
return dict([(f, countcalls.count(f)) for f in countcalls.__instances])
装饰器类countcalls, 拥有一个class level 变量 __instances = {}
, 相当于是Java里的静态变量. 该变量用于存储所有函数的调用次数统计, key为函数对象, value为该函数对象所初始化出的countcalls的实例.
countcalls类的实例拥有一个实例变量 self.__numcalls
, 并且会在装饰器被调用的时候更新数值. 即在 __call__()
函数中更新.
创建函数并使用类装饰器countcalls
@countcalls
def add(x, y):
return x + y
@countcalls
def sub(x, y):
return x - y
调用函数, 并通过countcalls的静态方法查看调用统计
if __name__ == "__main__":
print(add(2, 3))
print(add(10,23))
print(sub(5, 6))
counts = countcalls.counts()
print(counts)
输出结果
5
33
-1
{<function add at 0x000002856EC11E18>: 2, <function sub at 0x000002857076CA60>: 1}
网友评论