zoukankan      html  css  js  c++  java
  • 装饰器

    一. 装饰器

    定义:假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

    原则:基于开放封闭原则

    封闭原则:对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

    开放原则:对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

    1.实现目标:登录功能和index功能

    1 def login():
    2     user=input("请输入用户名:")
    3     pwd=input("请输入密码:")
    4     if user=="shy" and pwd=="123":
    5         print("登录成功")
    6     else:
    7         print("用户名或密码错误")
    8 def index():
    9     print("this is index")

    2.只有登录才能调用index函数

     1 def login():
     2     user=input("请输入用户名:")
     3     pwd=input("请输入密码:")
     4     if user=="shy" and pwd=="123":
     5         index()
     6     else:
     7         print("用户名或密码错误")
     8 def index():
     9     print("this is index")
    10 login()

    结果:只能调用index函数,不灵活

    3.登录后能调用各种函数

     1 def login(func):
     2     user=input("请输入用户名:")
     3     pwd=input("请输入密码:")
     4     if user=="shy" and pwd=="123":
     5         func()
     6     else:
     7         print("用户名或密码错误")
     8 def index():
     9     print("this is index")
    10 def foo():
    11     print("this is foo")
    12 login(foo)

    结果:不符合开放原则,导致所有调用index,foo的地方都要更改

    4.在保证index,foo开放的前提下,添加登录功能

     1 def login(func):
     2    def inner():
     3        user = input("请输入用户名:")
     4        pwd = input("请输入密码:")
     5        if user == "shy" and pwd == "123":
     6            func()
     7        else:
     8            print("用户名或密码错误")
     9    return inner
    10 
    11 def index():
    12     print("this is index")
    13 def foo():
    14     print("this is foo")
    15 index=login(index)
    16 index()
    17 foo=login(foo)
    18 foo()

    结果:每一个只有登录才能调用的函数都要加上这句话index=login(index)

    5.Django为其提供了快捷的方法,语法糖(装饰器)

     1 def login(func):
     2    def inner():
     3        user = input("请输入用户名:")
     4        pwd = input("请输入密码:")
     5        if user == "shy" and pwd == "123":
     6            func()
     7        else:
     8            print("用户名或密码错误")
     9    return inner
    10 @login
    11 def index():
    12     print("this is index")
    13 @login
    14 def foo():
    15     print("this is foo")
    16 # index=login(index)  #语法糖相当于这句话
    17 index()

    结果:在每个需要登录才能调用的方法上加@login

    6.:在每个函数执行后都打印执行该函数的所需时间

     1 def timer(func):
     2     import time
     3     def inner():
     4         start=time.time()
     5         func()
     6         end=time.time()
     7         cost=end-start
     8         print(cost)
     9     return inner
    10 @timer
    11 def add():
    12     s=0
    13     for  i in range (30000000):
    14         s+=i
    15     print(s)
    16 add()

    7.带参数的装饰器

     1 def timer(func):
     2     import time
     3     def inner(x,y):
     4         start=time.time()
     5         func(x,y)
     6         end=time.time()
     7         cost=end-start
     8         print(cost)
     9     return inner
    10 @timer
    11 def add(x,y):
    12     print(x+y)
    13 add(50,54)

    8.满足各个函数参数不等的装饰器

     1 def timer(func):
     2     import time
     3     def inner(*args,**kwargs):
     4         start=time.time()
     5         func(*args,**kwargs)
     6         end=time.time()
     7         cost=end-start
     8         print(cost)
     9     return inner
    10 @timer
    11 def add(x,y):
    12     print(x+y)
    13 add(50,54)
    14 @timer
    15 def x(x,y,z):
    16     print(x*y*z)
    17 x(1,2,3)

     

  • 相关阅读:
    一文学会Go语言
    只用120行Java代码写一个自己的区块链
    精通libGDX游戏开发-RPG实战-欢迎来到RPG的世界
    精通libGDX游戏开发-RPG实战-开发游戏的基本前提
    libGDX开发环境搭建-Android Studio 最新版
    linux下redis的最佳实践(Master-Slave)
    使用Redis实现高并发分布式序列号生成服务
    [libGDX游戏开发教程]使用libGDX进行游戏开发(12)-Action动画
    [libgdx游戏开发教程]使用Libgdx进行游戏开发(11)-高级编程技巧 Box2d和Shader
    [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐和音效
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9925697.html
Copyright © 2011-2022 走看看