Table of Contents
写在前面
修饰函数在某种程度上可以帮助程序员方便的代码复用等技巧, 灵活使用修饰函数可以起到事半功倍的效果.
Python 装饰器中的@wraps的作用:
- 装饰器的作用: 在不改变原有功能代码的基础上,添加额外的功能,如统计时间, 打log等
- @wraps(view_func)的作用: 不改变使用装饰器原有函数的结构(如__name__, doc)
- 不使用wraps可能出现的ERROR: view_func...endpoint...map...
使用技巧
技巧一, 统计函数的运行时间
示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- import functools import time def wrap_timer(func): @functools.wraps(func) def timer(*args, **kwargs): t_begin = time.time() result = func(*args, **kwargs) t_end = time.time() print(("%s(%s, %s)" % (func, args, kwargs))) print("Time: %f " % (t_end - t_begin)) return result return timer # 类中使用 class ClassTest: def __init__(self): pass @wrap_timer def test(self): time.sleep(10) # 单个函数使用 @wrap_timer def test_func(num): for i in range(num): time.sleep(1)
运行输出:
# 类测试 test_mode = ClassTest() test_mode.test() # 单函数测试 test_func(5) <function ClassTest.test at 0x7f14400bb510>((<__main__.ClassTest object at 0x7f144010d278>,), {}) Time: 10.010076 <function test_func at 0x7f144011c6a8>((5,), {}) Time: 5.005338
技巧二, 函数运行前后的log输出
示例:
#!/usr/bin/env python # -*- coding: utf-8 -*- def wrap_logger(func): @functools.wraps(func) def logger(*args, **kwargs): print(("%s(%s, %s)" % (func, args, kwargs))) print("before execute") result = func(*args, **kwargs) print("after execute") return result return logger # 类测试 class TestClass: def __init__(self): pass @wrap_logger def test(self, a, b, c): print(a, b, c) # 单函数测试 @wrap_logger def test_func(num): for i in range(num): time.sleep(1)
输出:
t = TestClass() t.test(1, 2, 3) test_func(5) <function TestClass.test at 0x7f14400bb950>((<__main__.TestClass object at 0x7f14400cea90>, 1, 2, 3), {}) before execute 1 2 3 after execute <function test_func at 0x7f1440360730>((5,), {}) before execute after execute