python-装饰器
开放封闭原则
手写装饰器函数
闭包与简单的装饰器
# 极简闭包装饰器
def decorator(func):
def f():
func()
return f()
def myfunc():
pass
decorator(func=myfunc)
import time
def decorator(func):
def f():
t0 = time.time()
func()
print(f'urs time:{time.time() - t0}')
return f()
def myfunc():
time.sleep(1)
print('myfunc11111')
def myfunc2():
time.sleep(2)
print('myfunc2222')
decorator(func=myfunc)
decorator(func=myfunc2)
装饰器 @ 语法糖
@use_time myfunc 相当于use_time(myfunc)(*args, **kwargs)
import time
def use_time(func):
def f():
t0 = time.time()
func()
print(f'urs time:{time.time() - t0}')
return f
@use_time
def myfunc():
time.sleep(0.5)
print('myfunc11111')
@use_time
def myfunc2():
time.sleep(0.6)
print('myfunc2222')
myfunc()
myfunc2()
import time
def use_time(func):
def f(*args):
t0 = time.time()
func(*args)
print(f'urs time:{time.time() - t0}')
return f
@use_time
def add(num0, num1):
time.sleep(0.5)
print(f'{num0} + {num1} = {num0 + num1}')
add(3, 4)
类装饰器
call 把class变成一个可调用对象
import time
class UseTime:
def __init__(self):
pass
def __call__(self, sleep_time, **kwargs):
t0 = time.time()
time.sleep(sleep_time)
print(f'urs time:{time.time() - t0}')
UseTime()(sleep_time=0.3)
类装饰器就是用 call 把class变成一个可调用对象
import time
class UseTime:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
t0 = time.time()
self.func(*args, **kwargs)
print(f'urs time:{time.time() - t0}')
@UseTime
def add(num0, num1):
time.sleep(0.5)
print(f'{num0} + {num1} = {num0 + num1}')
def add_str(str0, str1):
time.sleep(0.3)
print(f'{str0} + {str1} = {str0 + str1}')
add(3, 4)
UseTime(add_str)('fsdf', 'ddfgds')
含参类装饰器
再 call 中建立一个闭包,相当于闭包中的闭包
import time
class UseTime:
def __init__(self, sleep_time=0):
self.sleep_time = sleep_time
def __call__(self, func):
print(f'=================Usetime for {func.__name__} : ')
self.func = func
def f(*args, **kwargs):
t0 = time.time()
print(f'sleep time: {self.sleep_time}', end=' ')
time.sleep(self.sleep_time)
print(f'end!')
self.func(*args, **kwargs)
print(f'urs time:{time.time() - t0}')
return f
@UseTime(2)
def add(num0, num1):
# time.sleep(0.5)
print(f'{num0} + {num1} = {num0 + num1}')
# @UseTime(0.2)
def add_str(str0, str1):
# time.sleep(0.3)
print(f'{str0} + {str1} = {str0 + str1}')
add(3, 4)
UseTime(0.2)(add_str)('fsdf', 'ddfgds')
装饰器执行顺序
从上到下顺序压栈
import time
def print_func_name(func):
def f(*args, **kwargs):
print(f'-----------------{func.__name__}() run start!--------------------')
func(*args, **kwargs)
print(f'-----------------{func.__name__}() run end!--------------------')
return f
class UseTime:
def __init__(self, sleep_time=0):
print(f'=================Usetime __init__ start ')
self.sleep_time = sleep_time
print(f'sleep_time = {sleep_time}')
def __call__(self, func):
print(f'=================Usetime __call__ 0000000 for {func.__name__} : ')
self.func = func
def f(*args, **kwargs):
print(f'=================Usetime __call__ f() start for {func.__name__} : ')
t0 = time.time()
time.sleep(self.sleep_time)
self.func(*args, **kwargs)
print(f'=================Usetime __call__ f() end for {func.__name__} : ')
print(f'urs time:{time.time() - t0}')
return f
@print_func_name
@UseTime(2)
def add(num0, num1):
# time.sleep(0.5)
print(f'add start!')
print(f'{num0} + {num1} = {num0 + num1}')
print(f'add start!')
add(5, 6)
'''
结果:
sleep_time = 2
=================Usetime __call__ 0000000 for add :
-----------------f() run start!--------------------
=================Usetime __call__ f() start for add :
add start!
5 + 6 = 11
add start!
=================Usetime __call__ f() end for add :
urs time:76.14536690711975
-----------------f() run end!--------------------
'''
import time
def print_func_name(func):
def f(*args, **kwargs):
print(f'-----------------print_func_name {func}() run start!--------------------')
func(*args, **kwargs)
print(f'-----------------print_func_name {func}() run end!--------------------')
return f
class UseTime:
def __init__(self, func):
print(f'=================Usetime __init__ start ')
self.func = func
def __call__(self, *args, **kwargs):
print(f'=================Usetime __call__ f() start for {self.func.__name__} : ')
t0 = time.time()
self.func(*args, **kwargs)
print(f'=================Usetime __call__ f() end for {self.func.__name__} : ')
print(f'urs time:{time.time() - t0}')
# @print_func_name
# @UseTime
# @print_func_name
@UseTime
@print_func_name
def add(num0, num1):
time.sleep(0.5)
print(f'add start!')
print(f'{num0} + {num1} = {num0 + num1}')
print(f'add start!')
add(5, 6)
# UseTime(add)(1,2)
'''
结果:
=================Usetime __init__ start
=================Usetime __call__ f() start for f :
-----------------print_func_name <function test2.<locals>.add at 0x000001DD1DDD2F80>() run start!--------------------
add start!
5 + 6 = 11
add start!
-----------------print_func_name <function test2.<locals>.add at 0x000001DD1DDD2F80>() run end!--------------------
=================Usetime __call__ f() end for f :
urs time:0.5003499984741211
'''