装饰器
概念本质带参数的装饰器和不带参数的装饰器不带参数的装饰器:带参数的装饰器:
作用/优点多个装饰器的顺序使用例子日志装饰器实现类对象按照创建时间排序
概念
装饰器就是一个可以接受调用也可以返回调用的函数,该函数接受被装饰的函数作为其位置参数。 装饰器通过使用该参数来执行某些操作,然后返回原始参数或一些其他的调用
本质
装饰器可以让函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
因此定义装饰器的本质就是一个函数,只不过这个函数的功能是用来为其他函数添加额外的功能。
带参数的装饰器和不带参数的装饰器
不带参数的装饰器是普通的装饰器,需要两层函数。 带参数的装饰器可以看成是装饰器工厂,需要三层函数,因为要传递装饰器的参数,所以多了一层函数。
装饰器的简单使用:
不带参数的装饰器:
def check(func
):
print("验证权限")
def inner(identify
):
func
(identify
)
return inner
@check
def f1(user_id
):
if user_id
=="root":
print("允许root用户操作")
else:
print(f
"不允许{user_id}用户操作")
f1
("root")
运行结果:
带参数的装饰器:
def deco(arg
):
def inner1(func
):
def _cost(a
,b
):
func
(a
,b
)
print(f
"装饰器的参数是{arg}")
return _cost
return inner1
@deco
(1)
def fun1(a
,b
):
print(f
"我是真正的函数体,{a}+{b}={a+b}")
fun1
(1,3)
运行结果为: 这里可以看到,最外面的一层函数其参数是@deco(1)中的参数1,inner函数的参数是装饰器装饰的函数的引用,这里是fun1,最里面的函数的参数是func1函数的参数即1,3
作用/优点
装饰器最大的作用就是用来包装代码块,让其具有特定的功能。
装饰器有以下优点: • 模块化且清晰明确
• 代码重用
• 装饰器是显式的,增强可读性
多个装饰器的顺序
当有两个装饰器来装饰用一个函数的时候。离函数近的装饰器先进行装饰,装饰器先装饰完后将整个装饰结果给第一个装饰器进行装饰
即常说的:封装时自内而外(自下而上),执行时自外而内(自上而下)
def login_required(func
):
print("开始权限的验证")
def inner(username
,passwd
):
if username
=="root":
result
=func
(username
,passwd
)
return result
else:
print("权限不够")
exit
(0)
return inner
def login_valid(func
):
print("开始用户登录的验证")
def inner(username
,passwd
):
if passwd
==123456:
print("用户登录成功!")
func
(username
,passwd
)
return True
else:
print("密码错误")
return False
return inner
@login_valid
@login_required
def login(username
,passwd
):
print("欢迎root用户")
login
("root",123456)
运行结果为: 可以看到结果封装的时候是从下向上进行封装的,,但是执行的时候是先判断登录再判断权限,因次执行时是自上而下的顺序
使用例子
日志
import time
def input_log(name
):
import logging
logger
= logging
.getLogger
()
fh
= logging
.FileHandler
("test2.log",encoding
="utf-8")
ch
= logging
.StreamHandler
()
formatter
= logging
.Formatter
(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh
.setFormatter
(formatter
)
logger
.handlers
.clear
()
logger
.addHandler
(fh
)
logger
.addHandler
(ch
)
logger
.setLevel
(level
=logging
.DEBUG
)
logger
.debug
(f
"执行了{name.__name__}函数")
logger
.info
("logger info message")
logger
.warning
("this is warning message")
logger
.error
("this is error message")
logger
.critical
("this is critical message")
def log(func
):
print("log")
def inner(b
):
a
=func
(b
)
input_log
(func
)
return a
return inner
@log
def fun2(a
):
b
=a
+2
time
.sleep
(1)
print("func2 result:",b
)
return b
fun2
(2)
运行结果:
装饰器实现类对象按照创建时间排序
import functools
import time
def sortable_by_create_time(cls
):
original_init
=cls
.__init__
@functools
.wraps
(original_init
)
def new_init(self
,*args
,**kwargs
):
original_init
(self
,*args
,**kwargs
)
self
.create_time
=time
.time
()
cls
.__init__
=new_init
cls
.__lt__
=lambda self
,other
:self
.create_time
<other
.create_time
return cls
@sortable_by_create_time
class Sortable():
def __init__(self
,identifier
):
self
.identifier
=identifier
self
.create_time
=time
.time
()
def __repr__(self
):
return self
.identifier
yy
=Sortable
("yy")
time
.sleep
(0.1)
first
=Sortable
("first")
time
.sleep
(0.1)
second
=Sortable
("second")
time
.sleep
(0.1)
third
=Sortable
("third")
result
=[first
,second
,third
,yy
]
print(sorted(result
))
运行结果: