装饰器
装饰函数,扩展功能
装饰器作用
1.不修改函数的调用方式
2.给原来的函数添加新的功能
开发封闭原则
1.开发:对扩展开发
2.封闭:对修改封闭
示例
例1:计算代码运行时间
import time
def func():
start_time = time.time()
print('from the func')
time.sleep(1)
end_time = time.time()
print(end_time - start_time)
func()
# 执行结果
from the func
1.0009381771087646
例2:计算函数运行时间
def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print(end_time-start_time)
def func():
print('from the func')
time.sleep(1)
func()
timmer(func) # 传入函数名就得到该函数的执行时间
语法糖
import time
def timmer(func):
def inner():
start_time = time.time()
func()
end_time = time.time()
print(end_time-start_time)
return inner
@timmer # 相当于func = timmer(func)
def func(): # 被装饰的函数
print('from the func')
time.sleep(1)
func()
例3:带参数的装饰器
1.在装饰器外面再加一层函数
2.利用局部调用全局变量
3.不需要装饰器时需改标识
import time
# flag = True
flag = False
def timmer_out(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag:
start_time = time.time()
ret = func(*args,**kwargs)
end_time = time.time()
print(end_time-start_time)
return ret
else:
ret = func(*args, **kwargs)
return ret
return inner
return timmer
# timmer = timmer_out(flag)
# @timmer
@timmer_out(flag)
def func1():
time.sleep(0.5)
print('from func1')
@timmer_out(flag)
def func2():
time.sleep(0.5)
print('from func2')
func1()
func2()
例4:调用内置双下划线
from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs):
print('在被装饰函数执行前动作')
ret = func(*args,**kwargs)
print('在被装饰函数执行后动作')
return ret
return inner
@wrapper # holiday = wrapper()
def holiday(day):
'''
这是一个放假通知
:param day:
:return:
'''
print('放假时间%s'%day)
return 'happy'
ret = holiday(3)
print(ret)
print(holiday.__name__) # 查看函数名
print(holiday.__doc__) # 查看注释
类中方法
1.普通方法,没有任何参数,只能类来调用。
2.绑定方法:1)绑定到对象;2)绑定到类
3.静态方法:无论对象还是类都可以调用
class MyClass():
# 普通方法
def methoda():
print("普通方法")
# 绑定方法(绑定对象)
def methodb(self):
print("绑定到对象方法")
# 绑定方法(绑定到类)
@classmethod
def methodc(cls):
print(cls)
print("绑定到类方法")
# 静态方法
@staticmethod
def methodd(arg):
print("静态方法")
# 实例化
obj = MyClass()
MyClass.methoda() # 普通方法
obj.methodb() # 绑定方法(绑定对象)
MyClass.methodb(111) # 绑定方法(绑定对象) 手动传参
MyClass.methodc() # 绑定方法(绑定到类)
obj.methodc() # 绑定方法(绑定到类)
obj.methodd(111) # 静态方法
MyClass.methodd(111) # 静态方法
# 默认在类外,动态添加动态方法
obj.func = lambda : print(123)
obj.func()
"""
执行结果:-----
普通方法
绑定到对象方法
绑定到对象方法
<class '__main__.MyClass'>
绑定到类方法
<class '__main__.MyClass'>
绑定到类方法
静态方法
静态方法
123
"""