zoukankan      html  css  js  c++  java
  • day12

    # day12

    ## 复习

    ```python

    1.函数对象:函数名
    def fn(): pass
    1) f = fn
    2) def fun(fn): pass
    3) def func(): return fn
    4) dic = {'函数': fn} | ls = [fn]

    2.名称空间与作用域
    LEGB
    len("abc")
    len = 10
    del len
    len("abc")
    global关键字 L => G

    num = 100
    def fn():
    global num
    num = 10
    def fn1():
    global
    num = 20
    fn1()
    fn()
    print(num)


    3.函数嵌套定义与闭包
    def f1():
    num = 10
    def f2():
    print(num)

    def f1():
    def f2():
    def f3():
    def f4():
    pass
    什么是闭包:f2,定义在函数内部的 函数


    # 今天
    # 装饰器:就是闭包的一种应用
    ```

    ## nonlocal关键字

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

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

    # 案例:

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

    '''
    # num = 0
    # def fn():
    # global num # L => G, 将局部名字与全局名字统一
    # num = 20
    # fn()
    # print(num)


    def outer():
    # global num
    num = 0
    def inner():
    # 如果想在被嵌套的函数中修改外部函数变量(名字)的值
    nonlocal num # 将 L 与 E(E中的名字需要提前定义) 的名字统一
    num = 10
    print(num)
    inner()
    print(num)
    outer()
    # print(num)
    '''
    ```

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

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

    # 1.0版本
    def fn():
    print('fn run')
    # fn()

    # 2.0版本
    # def fn():
    # print('fn run0')
    # print('fn run1')
    # print('fn run2')
    # fn()

    # 修改了源代码,没有更改调用方式,对外调用方式还是原来的,但功能要有所增加(开放)
    # def fn():
    # print('fn run0')
    # print('fn run')
    # print('fn run2')
    # fn()

    # 更改了调用方式,没有修改原功能代码(封闭)
    def wrap(fn):
    print('fn run0')
    fn()
    print('fn run2')
    wrap(fn)

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

    ## 装饰器

    ```python
    # 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
    # 被装饰的函数: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 vase():
    # print('插花')
    # vase()

    # 增加一个绘画后观赏功能:不满足开放封闭原则,修改了源代码
    # def vase():
    # print('插花')
    # print('绘画:进行观赏')
    # vase()

    # 增加一个绘画后观赏功能:不满足开放封闭原则,修改了调用方式
    # def wrap(fn):
    # vase()
    # print('绘画:进行观赏')
    # wrap(vase)

    # 虽然满足了开放封闭原则,但是出现了函数调用的死循环
    # def fn():
    # vase()
    # print('绘画:进行观赏')
    # vase = fn
    # vase()

    # 了解:满足开放封闭原则,且可以达到装饰器的作用:拓展功能
    # def vase():
    # print('插花')
    # tag = vase # 暴露在全局:很容易被修改掉
    # def fn():
    # tag()
    # print('绘画:进行观赏')
    # vase = fn
    # vase()


    # def wrap(tag):
    # def fn():
    # tag()
    # print('绘画:进行观赏')
    # return fn
    # vase = wrap(vase)
    # vase()


    def vase():
    print('插花')

    # 下方的函数嵌套结构就是装饰器
    def wrap(tag):
    def fn():
    tag() # 原有的vase
    print('绘画:进行观赏')
    return fn # 拓展功能后的vase
    vase = wrap(vase) # 将拓展功能后的功能函数重新赋值给vase


    vase() # 功能拓展了,且调用方式不变

    ```

    ## @语法糖: @外层函数

    ```python
    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 outer(fn):
    def inner():
    fn()
    print("绘画:进行观赏")
    return inner


    def wrap(fn):
    def inner():
    fn()
    print('摆放功能')
    return inner


    # 语法糖 | 笑笑语法
    @wrap
    @outer # <==> vase = outer(vase)
    def vase():
    print('插花')
    # vase = outer(vase)

    vase()

    # 总结:一个函数可以被任意一个相关装饰器装饰,也可以被任意几个装饰器装饰
    # 注:装饰的顺序会影响新增功能的执行顺序
    ```

    ## 有参有返的函数被装饰

    ```python
    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的返回值
    """


    原版
    # 增加一个账号处理功能:3位及以上英文字符或汉字
    def check_usr(fn):
    def inner(usr, pwd):
    if not (len(usr) >= 3 and usr.isalpha()):
    print('账号验证失败')
    return False
    result = fn(usr, pwd) # login
    return result
    return inner

    # 增加一个密码处理功能:6位及以上英文和数字
    def check_pwd(fn):
    def inner(usr, pwd):
    if not (len(pwd) >= 6 and pwd.isalnum()):
    print('密码验证失败')
    return False
    return fn(usr, pwd)
    return inner

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

    res = login('abc', '123qwe') # inner
    print(res)

    ```

    ## 装饰器最终写法

    ```python

    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)
    ```

    ## 带参装饰器:了解

    ```python
    # 了解
    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()
    ```

    ## 登录认证功能

    ```python
    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()
    ```

  • 相关阅读:
    Syntax error, insert "]" to complete MemberExpression XXX.js (Java Web Project 导入Jquery的文件后报错)
    Unicode 转换成 Ascii (把Unicode 中文字符串输入到文本中)
    Static控件响应鼠标事件
    在Window 7 64位操作系统上安装Oracle 10g 及 配置PLSQL Developer 8.0.4图解
    LPSTR LPCSTR LPWSTR LPCWSTR区别
    C++ Builder 全部API函数列表
    CPropertySheet标签页 实现各个CPropertyPage页面之间的切换
    C#中如何从字符串中提取数字
    如何用SQL统计某个字符在一个字符串中出现的次数
    MVC中--异常详细信息: System.ArgumentNullException: 值不能为 null。 参数名: value
  • 原文地址:https://www.cnblogs.com/huangxuanya/p/10642394.html
Copyright © 2011-2022 走看看