python函數修飾符@的使用

python函數修飾符@的做用是爲現有函數增長額外的功能,經常使用於插入日誌、性能測試、事務處理等等。python

建立函數修飾符的規則:
(1)修飾符是一個函數
(2)修飾符取被修飾函數爲參數
(3)修飾符返回一個新函數
(4)修飾符維護被維護函數的簽名app

例子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__)

運行結果:spa

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__)

運行結果:code

test1
test2

例子3:被修飾函數帶參數blog

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結束 ...
相關文章
相關標籤/搜索