装饰器是从英文decorator翻译过来的,从字面上来看就是对某个东西进行修饰,增强被修饰物的功能,下面我们对装饰器做下简单介绍,我来为大家科普一下关于python是什么?下面希望有你要的答案,我们一起来看看吧!
python是什么
装饰器是从英文decorator翻译过来的,从字面上来看就是对某个东西进行修饰,增强被修饰物的功能,下面我们对装饰器做下简单介绍。
一、怎么编写装饰器
装饰器的实现很简单,本质是一个可调用对象,可以是函数、方法、对象等,它既可以装饰函数也可以装饰类和方法,为了简单说明问题,我们实现一个函数装饰器,如下代码:
# 定义一个装饰器
def decorator(f):
def wrap(*pos, **kwarg):
print("enter function", f.__name__)
ret = f(*pos, **kwarg)
print("leave function", f.__name__)
return ret;
return wrap
# 使用上面定义的装饰器
@decorator
def sum(a, b):
print("a b =", a b)
# 输出:
# enter function sum
# a b = 3
# leave function sum
sum(1,2)
有了这个装饰器,我们就可以打印出什么时候开始和结束调用函数,对于排查函数的调用链非常方便。
二、带参数的装饰器
上面的例子无论什么时候调用sum都会输出信息,如果我们需要按需输出信息怎么实现呢,这时就要用到带参数的装饰器了,如下代码:
def decorator(debug=0):
def wrap1(f):
def wrap2(*pos, **kwarg):
if debug:
print("enter function", f.__name__)
ret = f(*pos, **kwarg)
if debug:
print("leave function", f.__name__)
return ret;
return wrap2;
return wrap1
@decorator()
def sum(a, b):
print("a b =", a b)
@decorator(debug=1)
def multi(a, b):
print("a * b =", a * b)
# 输出:
# a b = 3
sum(1,2)
# 输出:
# enter function multi
# a * b = 2
# leave function multi
multi(1,2)
对sum使用装饰器时没有参数,这时debug为0,所以调用sum时不会输出函数调用相关信息。
对multi使用装饰器时有参数,这时debug为1,所以调用multi时会输出函数调用相关信息。
三、函数名字问题
当我们打印被装饰后的函数名字时,不知道大家有没发现输出的不是函数本身的名字,如下代码会输出‘wrap’而不是‘sum’:
# 定义一个装饰器
def decorator(f):
def wrap(*pos, **kwarg):
return f(*pos, **kwarg)
return wrap
# 使用上面定义的装饰器
@decorator
def sum(a, b):
print("a b =", a b)
# 输出:
# wrap
print(sum.__name__)
有时这种表现并不是我们想要的,我们希望被装饰后的函数名字还是函数本身,那要怎么实现呢?很简单,只需要引入functools.wraps即可,如下代码就会输出‘sum’了:
from functools import wraps
# 定义一个装饰器
def decorator(f):
# 使装饰后的函数保留原有名字
@wraps(f)
def wrap(*pos, **kwarg):
return f(*pos, **kwarg)
return wrap
# 使用上面定义的装饰器
@decorator
def sum(a, b):
print("a b =", a b)
# 输出:
# sum
print(sum.__name__)
看完后是不是觉得python装饰器很简单,只要了解它的本质,怎么写都行,有好多种玩法呢。
,