一、装饰器
python的装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。简单的说装饰器就是一个用来返回函数的函数
- 它能使函数的功能得到扩充,而同时不用修改函数本身的代码。
- 它能够增加函数执行前、执行后的行为,而不需对调用函数的代码做任何改变。
执行流程:在执行装饰器修饰的函数时,python解释器会将被装饰的函数当成参数传入装饰器函数中。将装饰器函数的返回值当成函数调用,被装饰函数的参数继续传递给装饰器函数的返回值。
二、函数装饰器
2.1 简单装饰器
以下代码, 是一个简单的装饰器
def func(f):
print("%s执行结果" % f.__name__, end=": ")
f()
def test():
print("hello world")
func(test)
func
函数是装饰器函数test
函数是被装饰函数- 功能就是, 在不修改
test
函数的代码前提下, 增加一个输出函数名的功能.
2.2 装饰器
不带参数的装饰器
def decorator(func):
def run(*args, **kwargs):
print("函数%s执行结果: %d" % (func.__name__, func(args[0], args[1])))
return run
@decorator
def mul(a, b):
return a * b
mul(3, 4) # 输出 函数mul执行结果: 12
@
运算符: 标记装饰器- 装饰器执行机制:
- 被装饰的函数
mul
在调用时, 被解释器检查到有装饰器标志. - 不会立即执行
mul
函数, 解释器会将mul
函数当参数, 传递到装饰器函数decorator
内部. - 由装饰器函数的内部
run
函数对mul
函数进行装饰. - 当完成修饰函数
mul
后, 装饰器函数会将其内部函数run
返回, 并当成函数进行调用.mul
函数的参数, 则会传递到装饰器函数返回的run
函数.
- 被装饰的函数
示例
使用装饰器, 要求打印出是哪个函数执行的结果
def func(f):
def run():
print("%s执行结果" % f.__name__, end=": ")
f()
return run
@func
def test():
print("hello world")
# func(test)
test()
带参数的装饰
实现一个计算功能, 要求可以查看是谁调用的这个计算功能
def set_name(name):
def decorator(func):
def run(*args, **kwargs):
print("%s调用计算函数%s执行结果为: %.2f" %(name, func.__name__, func(args[0], args[1])))
return run
return decorator
@set_name("小芳")
def div(a, b):
return a / b
div(3, 2)
set_name("小芳")
: 因为对set_name
进行调用,set_name
函数已被执行. 返回值是decorator
函数- 可以将
@set_name('小芳')
理解为@decorator
. 这样就可以将被装饰函数传入到内层函数
三、内置装饰器
property
: 属性装饰staticmethod
: 静态方法装饰classmethod
: 类方法装饰器
class Cls:
@property # 以属性形式调用方法
def test01(self):
return '以属性形式调用方法'
@staticmethod # 不会自动传入self
def test02():
print('不会自动传入实例')
@classmethod
def test03(cls):
print('将类自动传入')
四、类装饰
class Decorator:
def __init__(self, fun):
self.fun = fun
def __call__(self, *args, **kwargs):
print("函数%s执行结果: %d" % (self.fun.__name__, self.fun(args[0], args[1])))
@Decorator
def minus(a, b):
return a - b
minus(20, 3)
- 装饰器函数的返回值, 当成了函数继续调用, 被装饰函数的参数就传递给了装饰器函数的返回值
- 使用类装饰器, 必须定义
__init__
和__call__
两个方法__init__
方法用于接收被装饰的函数名__call__
方法用于编写修饰 被装饰函数的逻辑, 也即是接受被装饰函数的参数