在调用某个方法前,想调用一些额外的东西。
个人感觉就和C++里面,带一个函数指针的的参数,在某个函数执行前,调用这个函数指针,或者,在某个函数中,直接调用这个函数。比如插入日志等。功能。
但在python可以使用@标识符,进行函数装饰器
这个和java反射有异曲同工之妙(应该说注解,但注解的本质就是反射)
如下python
- def bar1():
- print("[debug] bar1 is running")
- print("i am bar1")
-
- def bar2():
- print("[debug] bar2 is running")
- print("i am bar2")
-
-
- if __name__ == "__main__":
- bar1()
- bar2()
程序运行截图如下:
开始用了,最原始的方式
- def use_logging(func_name):
- #print("[debug]" + func_name + "is running")
- print("[debug] %s is running" % func_name)
-
-
- def bar1():
- use_logging("bar1")
- print("i am bar1")
-
- def bar2():
- use_logging("bar2")
- print("i am bar2")
-
- if __name__ == "__main__":
- bar1()
- bar2()
这里就是在函数里面调用其他函数,
下面是使用古老装饰器模式方式:
使用装饰器,这个是古老的方式,用C/C++来理解就是func是一个函数指针,use_logging函数把func的名字打印后,把指针返回来,然后给bar1,bar1再调用,即可
- def use_logging(func):
- def wrapper(*args, **kwargs):
- print("[debug] %s is running" % func.__name__)
- return func(*args, **kwargs)
- return wrapper
-
-
- def bar1():
- print("i am bar1")
-
- def bar2():
- print("i am bar2")
-
- if __name__ == "__main__":
- bar11 = use_logging(bar1)
- bar11()
- bar22 = use_logging(bar2)
- bar22()
程序运行截图如下:
下面是新时代写法,和Java注解差不多,从这里可以看到Java和Python写代码,的确比C/C++爽。
- def use_logging(func):
- def wrapper(*args, **kwargs):
- print("[debug] %s is running" % func.__name__)
- return func(*args, **kwargs)
- return wrapper
-
- @use_logging
- def bar1():
- print("i am bar1")
-
- @use_logging
- def bar2():
- print("i am bar2")
-
- if __name__ == "__main__":
- bar1()
- bar2()
程序运行截图如下:
下面是带参数的函数装饰器
- def use_logging(level = "debug"):
- def decorator(func):
- def wrapper(*args, **kwargs):
- print("[%s] %s is running" % (level, func.__name__))
- return func(*args, **kwargs)
- return wrapper
- return decorator
-
- @use_logging()
- def bar1():
- print("i am bar1")
-
- @use_logging(level = "error")
- def bar2():
- print("i am bar2")
-
- if __name__ == "__main__":
- bar1()
- bar2()
程序运行截图如下: