(修饰器本身也是个高阶函数)
修饰器
修饰器本身有点类似于模板, 函数“被修饰”成功能更健全的函数, 修饰器本质上属于闭包函数
# 示例1(修饰器实现原理)
# =========================================
# 修饰器函数
def decorator(f):
print("this is decorator")
return f()
# 被修饰函数
def function():
print("function")
return 0
print( decorator(function) )
使用上述的方法使得函数本身不易读,如果函数还须更加麻烦的操作, 这时,修饰器就登场了
基本语法
修饰器基本语法
# =========================================
# 修饰器函数
import functools # 导入函数工具模块
def decorator(f): # 修饰器函数
@functools.wraps(f) # 拷贝“被修饰”函数的全部属性
def inside_function():
pass # “函数体”(根据需求合理是指)
return f() # 修饰过后函数的返回值(根据需求合理设置)
return inside_function
@decorator # 修饰器
def function(): # 被修饰函数
pass
return 0
function() # 使用被修饰过后的函数
# =========================================
# 说明
pass :修饰需要添加的语句
return f() :返回被修饰函数的返回值
decorator :修饰器函数名
@ :修饰器关键字
@decorator :修饰器
@functools.wraps(f) :拷贝被修饰函数中的所有属性
import functools :需要用到的模块
# 示例2(修饰器案例)
# =========================================
import functools
def decorator(f):
@functools.wraps(f)
def inside_function():
print("Dectorator")
return f()
return inside_function
@decorator
def fun():
print("function")
return 0
print( fun() )
# =========================================
输出
this is decorator
function
0
拷贝原函数属性
functools.wraps
:是functools中的一个模块,作用是拷贝函数属性 例如把被修饰函数中的__name__
属性拷贝到修饰器函数中 就不需要通过decorator.__name__
=function.__name__
的方式来实现 如果不这样操作,修饰器修饰过后,会变成“另外一个函数”
import functools
def decorator(f):
@functools.wraps(f) # 拷贝function中的所有属性到修饰器中
def inside():
print(f.__name__) # 检测修饰函数的—__name__属性
return f()
return inside
@decorator
def function():
print(function.__name__)# 检测“被修饰”函数的—__name__属性
function()
# =========================================
输出
function
function
import functools
def decorator(f):
#@functools.wraps(f) # 关闭拷贝
def inside():
print(f.__name__) # 检测修饰函数的—__name__属性
return f()
return inside
@decorator
def function():
print(function.__name__)# 检测“被修饰”函数的—__name__属性
function()
# =========================================
输出
function
inside
带参修饰器
如果希望修饰器能够带参数,就必须再套一层函数 基础修饰器要两层函数 带参数修饰器要三层函数
import functools
def decorator(value):
print("print ",value)
def inside_decorator(f):
@functools.wraps(f)
def inside_function():
return f()
return inside_function
return inside_decorator
@decorator("decorator") # 修饰器函数也可以接受参数了
def function():
print("function")
function()
传递参数
修饰器中的参数必须和“被修饰”函数的参数保持一致
import functools
def decorator(f):
@functools.wraps(f)
def inside(a, b): # inside()中的参数必须和,“被修饰”函数 function的参数保持一致
print("insdie():",a, b)
return f(a,b)
return inside
@decorator
def function(a,b):
print("function():",a,b)
function("string","str")
# =========================================
输出
insdie(): string str
function(): string str
但是在实际操作中,修饰器只有一个,而被修饰函数可以有无数个, 根据被修饰函数的功能不同,会有不一样的参数,这种情况下我们没办法要求所有的函数都有统一的参数
此时修饰器就可以使用,不定参数和拆包来解决这个问题
import functools
def decorator(f):
@functools.wraps(f)
def inside(*c): # 定义函数时,使用*可以作为不定参数
print("insdie():",*c) # 调用参数时,使用*可以进行拆包
return f(*c)
return inside
@decorator
def function(a,b):
print("function():",a,b)
@decorator
def func(a):
print("func():",a)
function("string","str")
func("Hibari")
# =========================================
输出
insdie(): string str
function(): string str
insdie(): Hibari
func(): Hibari