python装饰器
先理解闭包函数
闭包:如果在一个函数的内部定义了另一个函数,外部的函数叫他外函数,内部的函数叫他内函数。
- 在一个函数中定义了一个内函数
- 内函数里运用了外函数的临时变量
- 外函数的返回值是内函数
# 外函数
def outer(a):
# 内函数
def inner(b):
# 引用外函数的变量a
return a + b
# 将内函数返回
return inner
if __name__ == '__main__':
# 传入a,实例化外函数,因a被被函数使用,地址存在内存中供inner函数使用
out = outer(1)
# 打印结果:<function outer.<locals>.inner at 0x0000029E27ED4F28>
print(out)
# 传入b,输出return a + b, 打印结果:3
print(out(2))
装饰器:Decorator
又称语法糖,用于扩展函数的功能
闭包写法
def added(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print("执行了内函数")
print("执行了外函数")
return wrapper
def add(x, y):
print(x+y)
adds = added(add)
adds(1, 2)
# 运行结果
--> 执行了外函数
--> 3
--> 执行了内函数
装饰器写法
def added(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
print("执行了内函数")
print("执行了外函数")
return wrapper
@added
def add(x, y):
print(x+y)
add(1, 2)
# 运行结果
--> 执行了外函数
--> 3
--> 执行了内函数
优点:简化代码,易维护,增加可读性,@added = adds = added(add)
带参数的装饰器
def info(value):
def decorator(func):
def wrapper(*args, **kwargs):
print(value)
return func(*args, **kwargs)
return wrapper
return decorator
@info(value='这是装饰器参数')
def say():
print('hello')
say()
补充:python函数加括号和不加括号的区别
- 不带括号时,调用的是函数本身
- 带括号(此时必须传入需要的参数),调用的是函数的return结果
python内置装饰器
- @property
- @staticmethod
- @classmethod
共同点:作用在类的方法上
property 装饰器
用于类中的函数,我们可以像访问属性一样来获取一个函数的返回值
class Date:
year = "2021"
month = "10"
day = "01"
@property
def full_date(self):
return self.year + "-" + self.month + "-" + self.day
date = Date()
print(date.full_date)
staticmethod 装饰器
1、用于类中的函数,表示这个方法将会是一个静态方法
2、该方法无需实例化,可以直接被调用
3、该函数无需 self 参数
class Person:
@staticmethod
def say():
print('hello')
Person.say()
classmethod 装饰器
1、表示这个方法是一个类方法,该方法可以直接被调用无需实例化,
2、没有 self 参数,也无法访问实例化后的对象。
3、相对于 staticmethod 的区别在于它会接收一个指向类本身的 cls 参数。
class Person:
name = '朋友'
@classmethod
def say(cls):
print('hello:' + cls.name)
Person.say()
类装饰器
当我们调用一个对象时,实际上调用的是它的 __call__ 方法。
class Person:
def __call__(self):
print('我是 Person')
person = Person()
person()
使用
class Decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print('执行了__call__方法')
return self.func(*args, **kwargs)
@Decorator
def say():
print('hello')
say()
同一个函数使用多个装饰器
def updatex(func):
def wrapper(x,y):
x += 1
return func(x,y)
print("x增加了1")
return wrapper
def updatey(func):
def wrapper(x,y):
x += 1
y += 5
return func(x,y)
print("y增加了5")
return wrapper
@updatex
@updatey
def add(x, y):
print(x+y)
add(1,1)
# 输出结果
--> y增加了5
--> x增加了1
--> 9
测试例子
1、计算耗时
import time
def cons(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
cons_time = end_time - start_time
print("=========")
print(f"总耗时:{int(cons_time)}秒")
return wrapper
@cons
def loop():
i = 0
while True:
i += 1
if i > 500000:
break
print(i)
loop()
2、区分登录用户
from functools import wraps
def decorator(func):
# 指向原函数func的__name__
@wraps(func)
def wrapper():
if func.__name__ == "userA":
func()
else:
print("请先登录!")
return wrapper
@decorator
def userA():
print(f"{userA.__name__} 登录成功")
@decorator
def userB():
print(f"{userB.__name__} 登录成功")
userA()
userB()
================================================================================>
找不到坚持下去的理由,那就找一个重新开始的理由,生活本来就这么简单。

浙公网安备 33010602011771号