本节给大家总结一下装饰器
# 在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数增加新的功能 def login(index): def fun(): user_name = 'python' pw = '123456' user = input('请输入帐号') password = input('请输入密码') if user == user_name and password == pw: index() # 调用传入的函数 也就是调用传入的index 这个是个变量跟调用的函数名无关可以随意更改 else: print('帐号或者密码错误') return fun @login # @login : 语法糖 --> index = login(index) 会把index 当作一个参数传入到login()函数中 去执行login函数 def index(): print('这个是首页') index() # index = login() # # index() # 带参数的装饰器 def add(func): def fun(a, b): print('相乘:', a * b) func(a, b) return fun # add_num = add(add_num) 在fun函数中需要传参 a, b 先调用fun 然后通过fun 再调用func func()也就是add_num add_num需要两个参数 # 所以给他传入, 因为调用add_num 调用了add函数然后调用了fun函数,我们给add_num传入了两个参数 此时需要给fun函数增加两个参数来接受 # 给add_num 传入的参数, 然后调用了 func()函数 因为func函数也就是传入的add_num函数,add_num函数传入两个参数,也需要在这里给func() # 函数也增加两个参数来调用add_num 函数 @add def add_num(a, b): print('相加:', a + b) add_num(1, 2) # 装饰有参数的函数和没有参数的函数 def add_1(func): def fun(*args, **kwargs): print('调用装饰器') # func(*args, *kwargs) return func(*args, *kwargs) return fun @add_1 def index_1(): print('第二个首页') @add_1 def add_num_1(a, b): print('相加:', a + b) index_1() print('-----------------------') add_num_1(1, 2) # 装饰器装饰类 类调用装饰器必须在装饰器里面写return 函数不一定要写 不写的话没有对象返回 @add_1 # MyClass = add_1(MyClass) class MyClass: def __init__(self): print('这是类') m = MyClass() print('m的值是', m) # m是一个对象 —————————————————————————————————————————————————————————————————————————————————————————————————— import time def count_time(func): def time_1(): start_time = time.time() func() end_time = time.time() print('运行时间是{:.5f}'.format(end_time - start_time)) return time_1 def game(func): def t(): for i in range(1, 4): a = input('猜年龄:') if int(a) == 18: print('猜对了') break else: print('本轮游戏结束,你猜错了') func() return t # 多个装饰器装饰同一个函数 @game @count_time def add(): time.sleep(5) print('这个是需要被装饰的函数') add() # 内置装饰器 class MY(object): @classmethod # 被classmethod装饰之后,该方法就是一个类方法 def add_2(cls): # cls代表的是类本身 self代表的是实例本身 cls类可以调用 self无法用类调用 print('add') @staticmethod # 静态方法 实例和类都可以调用 def stat(): print('这个是静态方法') @property # 用来装饰只读属性的方法 def read_attr(self): print('1') a = 1 return a t = MY() t.read_attr # 可以不用加()就可以调用
# 通过类来实现装饰器 __call__
import time
time class Tow(object): def __init__(self, fun): self.__fun = fun # 在这初始化函数,使call可以接收到外部传入的函数
def __call__(self, *args, **kwargs): start_time = time.time() self.__fun(*args, *kwargs) print('调用装饰器') end_time = time.time() a = end_time - start_time print(a) @Tow def func(): time.sleep(3) print('函数') func() # 单例模式装饰器 def single(cls): instance = {} def fun(*args, **kwargs): if cls in instance: return instance[cls] else: instance['cls'] = cls(*args, **kwargs) return instance['cls'] return fun @single class One(): pass @single class Tow(): pass