zoukankan      html  css  js  c++  java
  • Day 12 开放封闭原则,装饰器初识

    nonlocal关键字

    # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一

    # 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值

    # 案例:

    def outer():
       num = 10
       print(num)  # 10
       def inner():
           nonlocal num
           num = 20
           p77rint(num)  # 20
       inner()
       print(num)  # 20

    开放封闭原则:不改变调用方式与源代码上增加功能

    '''
    1.不能修改被装饰对象(函数)的源代码(封闭)
    2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)
    '''

     

    装饰器

    # 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
    # 被装饰的函数:fn
    # 外层函数:outer(func) outer(fn) => func = fn
    # 替代版函数: return inner: 原功能+新功能

    def fn():
       print("原有功能")

    # 装饰器
    def outer(tag):
       def inner():
      tag()
           print(新增功能")
       return inner
    fn = outer(fn)              
                 
    fn()

     

    @语法糖: @外层函数

    def outer(f):
       def inner():
      f()
           print("新增功能1")
       return inner
                 
    def wrap(f):
       def inner():
      f()
           print("新增功能2")
       return inner              

    @wrap  # 被装饰的顺序决定了新增功能的执行顺序
    @outer  # <==> fn = outer(fn): inner      
    def fn():
       print("原有功能")

     

     

    有参有返的函数被装饰

    def check_usr(fn):  # fn, login, inner:不同状态下的login,所以参数是统一的
       def inner(usr, pwd):
           # 在原功能上添加新功能
           if not (len(usr) >= 3 and usr.isalpha()):
               print('账号验证失败')
               return False
           
           # 原有功能
           result = fn(usr, pwd)
           
      # 在原功能下添加新功能
           # ...
           
           return result
      return inner


    @check_usr
    def login(usr, pwd):
       if usr == 'abc' and pwd =='123qwe':
           print('登录成功')
           return True
       print('登录失败')
       return False

    # 总结:
    # 1.login有参数,所以inner与fn都有相同参数
    # 2.login有返回值,所以inner与fn都有返回值

    """
    inner(usr, pwd):
      res = fn(usr, pwd) # 原login的返回值
      return res


    login = check_usr(login) = inner

    res = login('abc', '123qwe') # inner的返回值
    """

     

    装饰器最终写法


    def wrap(fn):
       def inner(*args, **kwargs):
           print('前增功能')
           result = fn(*args, **kwargs)
           print('后增功能')
           return result
       return inner

    @wrap
    def fn1():
       print('fn1的原有功能')
    @wrap
    def fn2(a, b):
       print('fn2的原有功能')
    @wrap  
    def fn3():
       print('fn3的原有功能')
       return True
    @wrap
    def fn4(a, *, x):
       print('fn4的原有功能')
       return True

    fn1()
    fn2(10, 20)
    fn3()
    fn4(10, x=20)

     

    带参装饰器:了解

    # 了解
    def outer(input_color):
       def wrap(fn):
           if input_color == 'red':
               info = '33[36;41mnew action33[0m'
           else:
               info = 'yellow:new action'

           def inner(*args, **kwargs):
               pass
               result = fn(*args, **kwargs)
               print(info)
               return result
           return inner
       return wrap  # outer(color) => wrap


    color = input('color: ')
    @outer(color)  # @outer(color) ==> @wrap # func => inner
    def func():
       print('func run')

    func()

     

     

    登录认证功能

    is_login = False  # 登录状态

    def login():
       usr = input('usr: ')
       if not (len(usr) >= 3 and usr.isalpha()):
           print('账号验证失败')
           return False
       pwd = input('pwd: ')
       if usr == 'abc' and pwd =='123qwe':
           print('登录成功')
           is_login = True
       else:
           print('登录失败')
           is_login = False


    # 完成一个登录状态校验的装饰器
    def check_login(fn):
       def inner(*args, **kwargs):
           # 查看个人主页或销售功能前:如果没有登录先登录,反之可以进入其功能
           if is_login != True:
               print('你未登录')
               login()
           # 查看个人主页或销售
           result = fn(*args, **kwargs)
           return result
       return inner

    # 查看个人主页功能
    @check_login
    def home():
       print('个人主页')

    # 销售功能
    @check_login
    def sell():
       print('可以销售')

    home()

     

     

     

     

     

  • 相关阅读:
    C#(99):TreadPool
    C#(99):多线程锁:Mutex互斥体,Semaphore信号量,Monitor监视器,lock,原子操作InterLocked
    C#(99):Thead线程 System.Thread
    ASP.NET(99):WebService之WebMethod参数介绍
    C#(99):WCF之WebService
    Windows服务 System.ServiceProcess.ServiceBase类
    应用程序域 System.AppDomain,动态加载程序集
    C#(99):app.config/web.config配置文件增删改
    C#(99):文件读写(三)利用FileStream类操作字节数组byte[]、BinaryFormatter、内存流MemoryStream
    C#(99):文件读写(二)利用SteamReader和StreamWrite类处理字符串、FileSystemWatcher、BinaryReader/BinaryWriter
  • 原文地址:https://www.cnblogs.com/zhengyuli/p/10642756.html
Copyright © 2011-2022 走看看