Python 修飾符 @ 的用法匯總
為已經存在的函數A,添加新的功能B
一、Python 修飾符 @
1.1 例子:為函數 Fun_A 添加 Fun_B 的新功能
1.2 複雜一點的例子:嵌套
1.3 更複雜的例子:帶有參數
1.4 再複雜一點的例子:返回一個函數
二、functools 模塊中修改函數屬性的方法 @wraps
2.1 保留新功能的函數名
2.2 新增功能帶有多個參數
2.3 修飾符帶有參數
1.1 例子:為函數 Fun_A 添加 Fun_B 的新功能
1.2 複雜一點的例子:嵌套
1.3 更複雜的例子:帶有參數
1.4 再複雜一點的例子:返回一個函數
二、functools 模塊中修改函數屬性的方法 @wraps
2.1 保留新功能的函數名
2.2 新增功能帶有多個參數
2.3 修飾符帶有參數
一、Python 修飾符 @
1.1 例子:為函數 Fun_A 添加 Fun_B 的新功能
def Func_A(f):
f() # 在這裡添加新功能
print("Func_A is running")
f() # 在這裡也添加新功能
return
@Func_A # 調用 Func_A 並加入新功能
def Func_B(): # 新功能 Func_B 的定義
print("Func_B is running")
return
運行結果:
Func_B is running
Func_A is running
Func_B is running
1.2 複雜一點的例子:嵌套
def Func_1(f):
f()
print("Func_1 is running")
return
def Func_2(f):
print("Func_2 is running")
f()
return
@Func_1
def Func_3():
print("Func_3 is running")
@Func_2
def Func_4():
print("Func_4 is running")
運行結果:
Func_3 is running
Func_2 is running
Func_4 is running
Func_1 is running
1.3 更複雜的例子:帶有參數
def Func_A(f):
f("111") # 在這裡添加帶有參數新功能
print("Func_A is running")
f("222") # 在這裡也添加帶有參數新功能
return
@Func_A # 調用 Func_A 並加入新功能
def Func_B(s): # 新功能 Func_B 的定義
print(s+"Func_B is running")
return
運行結果:
111Func_B is running
Func_A is running
222Func_B is running
1.4 再複雜一點的例子:返回一個函數
def log(func):
def wrapper():
print('log開始 ...')
func("uuu")
print('log結束 ...')
return wrapper # 運行後會返回一個函數
@log # 用新的方法修飾 log 並運行
def test1(s):
print(s+'test1 ..')
@log
def test2(s):
print(s+'test2 ..')
print(log.__name__) # 即顯示原函數的名字
print(test1.__name__) # 顯示返回來的函數的名字,即 wrapper
print(test2.__name__) # 顯示返回來的函數的名字,即 wrapper
print('\n')
test1() # 由於返回了一個函數,即可以直接運行
print('\n')
test2() # 由於返回了一個函數,即可以直接運行
運行結果:
log
wrapper
wrapper
log開始 ...
uuutest1 ..
log結束 ...
log開始 ...
uuutest2 ..
log結束 ...
二、functools 模塊中修改函數屬性的方法 @wraps
前面的例子中看到,用 @ 修飾符添加新功能,返回一個函數,那新功能的函數名稱發生變化
這個變化我們希望避免
於是可以用 functools 模塊中修改函數屬性的方法 @wraps
2.1 保留新功能的函數名
from functools import wraps
def log(func):
@wraps(func)
def wrapper():
print('log開始 ...')
func()
print('log結束 ...')
return wrapper
@log
def test1():
print('test1 ..')
@log
def test2():
print('test2 ..')
print(test1.__name__)
print(test2.__name__)
print('\n')
test1()
print('\n')
test2()
運行結果:
test1
test2
log開始 ...
test1 ..
log結束 ...
log開始 ...
test2 ..
log結束 ...
2.2 新增功能帶有多個參數
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
# 首先這裡用修飾符添加新功能後,返回的是一個函數
# 這個函數的作用在於:
# 1、打印 'log開始 ...',打印函數名(通用功能)
# 2、運行函數特有功能,返回一個值
# 3、打印 'log結束 ...'(通用功能)
# 4、返回之前的值
answer_1 = test1('a') # 這裡直接運行了返回的函數 wrapper
print("\n")
answer_2 = test2('a', 'bc') # 這裡直接運行了返回的函數 wrapper
print("\n")
print(answer_1) # 打印返回值
print(answer_2) # 打印返回值
運行結果:
log開始 ... test1
test1 .. a
log結束 ...
log開始 ... test2
test2 .. a bc
log結束 ...
a
abc
2.3 修飾符帶有參數
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('module2')
def test2(s1, s2):
print('test2 ..', s1, s2)
return s1 + s2
answer_1 = test1('a')
print("\n")
answer_2 = test2('a', 'bc')
print("\n")
print(answer_1)
print(answer_2)
運行結果:
log開始 ... test1 module1
test1 .. a
log結束 ...
log開始 ... test2 module2
test2 .. a bc
log結束 ...
a
abc