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結束 …