python函数修饰符@的使用方法解析

  • 2019 年 11 月 28 日
  • 筆記

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_36670529/article/details/103132252

python函数修饰符@的作用是为现有函数增加额外的功能,常用于插入日志、性能测试、事务处理等等。

创建函数修饰符的规则:

  1. 修饰符是一个函数
  2. 修饰符取被修饰函数为参数
  3. 修饰符返回一个新函数
  4. 修饰符维护被维护函数的签名

例子1:被修饰函数不带参数

def log(func):      def wrapper():        print('log开始 ...')        func()        print('log结束 ...')      return wrapper    @log    def test():      print('test ..')    test()

运行结果:

log开始 … test .. log结束 …

例子2:使用functools模块提供的修改函数属性的方法wraps

def log(func):      def wrapper():        print('log开始 ...')        func()        print('log结束 ...')      return wrapper    @log    def test1():      print('test1 ..')      def test2():      print('test2 ..')    print(test1.__name__)    print(test2.__name__)

运行结果:

wrapper test2

可见test1的函数名称变了,如果某些代码用到就会出问题,可以使用functools模块提供的修改函数属性的方法wraps

from functools import wraps      def log(func):      @wraps(func)      def wrapper():        print('log开始 ...')        func()        print('log结束 ...')      return wrapper    @log    def test1():      print('test1 ..')      def test2():      print('test2 ..')      print(test1.__name__)    print(test2.__name__)

运行结果:

test1 test2

例子3:被修饰函数带参数

from functools import wraps    def log(func):      @wraps(func)      def wrapper(*args,**kwargs):        print('log开始 ...',func.__name__)        ret = func(*args,**kwargs)        print('log结束 ...')        return ret      return wrapper    @log    def test1(s):      print('test1 ..', s)      return s      @log    def test2(s1, s2):      print('test2 ..', s1, s2)      return s1 + s2    test1('a')    test2('a','bc')

运行结果:

log开始 ... test1 test1 .. a log结束 ... log开始 ... test2 test2 .. a bc log结束 ...

例子4:修饰符带参数,需要比上面例子多一层包装

from functools import wraps      def log(arg):      def _log(func):        @wraps(func)        def wrapper(*args,**kwargs):          print('log开始 ...',func.__name__, arg)          ret = func(*args,**kwargs)          print('log结束 ...')          return ret        return wrapper      return _log        @log('module1')    def test1(s):      print('test1 ..', s)      return s      @log('module1')    def test2(s1, s2):      print('test2 ..', s1, s2)      return s1 + s2    test1('a')    test2('a','bc')

运行结果:

log开始 … test1 module1 test1 .. a log结束 … log开始 … test2 module1 test2 .. a bc log结束 …