装饰器
装饰函数,扩展功能
装饰器作用
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 """