美文网首页
Python-闭包和修饰器

Python-闭包和修饰器

作者: 徐弱西 | 来源:发表于2019-07-14 16:39 被阅读0次

作用域

# 作用域:名字起作用的范围
# 作用:解决同名字可以共存问题 - 不同作用域相同名字的值都能在其作用域范围下进行使用
'''
四种作用域: LEGB
Built-in:内置作用域 - 所有文件所有地方都可以被访问
Global:全局作用域 - 在当前文件的所有位置
Enclosing:嵌套作用域 - 自身内部与内部的子函数
Local:局部作用域 - 只有自身内部
'''
# 加载顺序:Built-in > Global > Enclosing > Local
# 访问(查找)顺序:报错 < Built-in < Global < Enclosing < Local
# 作用范围:Built-in > Global > Enclosing > Local

闭包

# 闭包:定义在函数内部的函数,这个内部的函数就是闭包

# 应用场景:
# 1.可以去使用其他函数的内部变量,且还可以保证调用位置不变(闭包的函数对象作为那个函数的返回值)
def outer():
    count = 3000
    def fn():
        print(count)  # 能使用outer内部的变量count
    return fn
# 还是在外界调用
outer()()  # outer()() => fn() => 调用fn


# 2.延迟执行(外层函数可以为内存函数传递参数)
import requests
def outer(url):
    def show_html():
        response = requests.get(url)
        print(response.text)
    return show_html

# 制作 爬百度与新浪的 函数对象
show_baidu = outer('https://www.baidu.com')
show_sina = outer('https://www.sina.com.cn')

# 延迟到需求来了,需要爬百度,就用百度函数对象,需要爬新浪,就用新浪函数对象
show_baidu()
show_sina()
show_baidu()
code:
# closure:闭包
# 闭包:定义在函数内部的函数,这个内部的函数就是闭包

# 应用场景:
# 1.可以去使用其他函数的内部变量,且还可以保证调用位置不变(闭包的函数对象作为那个函数的返回值)
def outer():
    count = 3000
    def fn():
        print(count)  # 能使用outer内部的变量count
    return fn
# 还是在外界调用
outer()()  # outer()() => fn() => 调用fn

# 2.延迟执行(外层函数可以为内存函数传递参数)
import requests

# def show_html(url):
#     response = requests.get(url)
#     print(response.text)
#
# show_html('https://www.baidu.com')
# show_html('https://www.baidu.com')
# show_html('https://www.sina.com.cn')

def outer(url):
    def show_html():
        response = requests.get(url)
        print(response.text)
    return show_html
# 制作 爬百度与新浪的 函数对象
show_baidu = outer('https://www.baidu.com')
show_sina = outer('https://www.sina.com.cn')
# 延迟到需求来了,需要爬百度,就用百度函数对象,需要爬新浪,就用新浪函数对象
show_baidu()
show_sina()
show_baidu()

装饰器

# 装饰器:装饰器就是闭包的一个应用场景
#       -- 外层函数与内存函数形成的闭包结构的一种综合使用

# 重点:开放封闭原则
# 开放:拓展功能的点是开放的 - 可以为之前的函数添加新功能
# 封闭:1.不能改变原函数的源代码  2.还有通过原函数的函数对象来调用函数

def huaping():
    print('插花功能')

temp = huaping
def my_huaping():
    temp()
    print('观赏功能')
huaping = my_huaping

huaping()

# ----------------------------------------

def huaping():
    print('插花功能')

def outer(temp):  # temp = huaping
    def my_huaping():
        temp()
        print('观赏功能')
    return my_huaping
huaping = outer(huaping)  # huaping = my_huaping

huaping()


# ----------------------------------------------
def outer(temp):  # temp = huaping
    def my_huaping():
        temp()
        print('观赏功能')
    return my_huaping

@outer  # huaping = outer(huaping)
def huaping():
    print('插花功能')
    
huaping()


# ------------------------------------------
# 被装饰的函数可能有参有返:装饰器模板,可以满足所有参数,且能装饰原函数返回值
def outer(func):  # temp = huaping
    def inner(*args, **kwargs):
        pass
        res = func(*args, **kwargs)
        pass
        return res
    return inner

@outer
def any_method():
    pass

code:
# 装饰器:装饰器就是闭包的一个应用场景
#       -- 外层函数与内存函数形成的闭包结构的一种综合使用


# def huaping():
#     print('插花功能')

# 需求:如何拓展一个原有函数的功能
#       -- 修改源代码
#       -- 创建一个包含该功能和其他新功能的新函数

# 开放封闭原则:
# 开放:拓展功能的点是开放的 - 可以为之前的函数添加新功能
# 封闭:1.不能改变原函数的源代码  2.还有通过原函数的函数对象来调用函数

# 错误一:修改了源代码
# def huaping():
#     print('插花功能')
#     print('观赏功能')
# huaping()

# 错误二:改变了调用方式
# def huaping():
#     print('插花功能')
# def my_huaping(fn):
#     fn()
#     print('观赏功能')
# my_huaping(huaping)

# 装饰器:满足开放封闭原则还能拓展新功能,简单
'''
def huaping():
    print('插花功能')

temp = huaping
# temp = '呵呵'
def my_huaping():
    temp()
    print('观赏功能')
huaping = my_huaping

huaping()
'''

# 装饰器演变一:
'''
def huaping():
    print('插花功能')

def outer(fn):  # fn = huaping
    # temp = huaping  # 可以提取到实参对形参传递
    def my_huaping():
        fn()
        print('观赏功能')
    return my_huaping
huaping = outer(huaping)  # 要整合该条逻辑

huaping()
'''

# 装饰器演变二:
def outer(fn):  # fn = 原功能的huaping
    def my_huaping():  # my_huaping => 新功能的huaping
        fn()
        print('观赏功能')
    return my_huaping

@outer  # huaping = outer(huaping)  被装饰的函数对象 = 装饰器外层函数对象(被装饰的函数对象)
def huaping():
    print('插花功能')

huaping()  # 被装饰后的my_huaping

装饰器案例

# 为登录功能添加账号检验功能:必须是3个及以上英文字母组成
def check_user(func):
    def inner(user, pwd):
        if not (user.isalpha() and len(user) >= 3):
            return '账号不合法'
        res = func(user, pwd)
        return res
    return inner

# 为登录功能添加密码检验功能:必须是3个及以上英文字母或数字组成
def check_pwd(func):
    def inner(*args, **kwargs):
        pwd = args[1]
        if not (pwd.isalnum() and len(pwd) >= 3):
            return '密码不合法'
        res = func(*args, **kwargs)
        return res
    return inner

# 对登录结果的修饰装饰器:True=>登录成功 False=>登录失败
def change_res(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        if res == True:
            return '登录成功'
        return '登录失败'
    return inner


# 装饰器被执行的过程是从上至下
@check_user  # login = check_user(func=login) = inner
@check_pwd
@change_res
def login(user, pwd):  # 被装饰的函数对象
    if user == 'owen' and pwd == '123':
        return True
    return False

user = input('user: ')
pwd = input('pwd: ')
res = login(user, pwd)

print(res)

code:

# 为登录功能添加账号检验功能:必须是3个及以上英文字母组成
def check_user(func):
    def inner(user, pwd):
        if not (user.isalpha() and len(user) >= 3):
            return '账号不合法'
        res = func(user, pwd)
        return res
    return inner

# 为登录功能添加密码检验功能:必须是3个及以上英文字母或数字组成
def check_pwd(func):
    def inner(*args, **kwargs):
        pwd = args[1]
        if not (pwd.isalnum() and len(pwd) >= 3):
            return '密码不合法'
        res = func(*args, **kwargs)
        return res
    return inner

# 对登录结果的修饰装饰器:True=>登录成功 False=>登录失败
def change_res(func):
    def inner(*args, **kwargs):
        res = func(*args, **kwargs)
        if res == True:
            return '登录成功'
        return '登录失败'
    return inner


@check_user  # login = check_user(func=login) = inner
@check_pwd
@change_res
def login(user, pwd):
    if user == 'owen' and pwd == '123':
        return True
    return False

user = input('user: ')
pwd = input('pwd: ')
res = login(user, pwd)

print(res)



# 装饰器:固定写法
def outer(func):
    def inner(*args, **kwargs):
        pass
        res = func(*args, **kwargs)
        pass
        return res
    return inner

@outer
def f1():  # 任意函数
    pass
f1()



相关文章

  • Python-闭包和修饰器

    作用域 闭包 code: 装饰器 code: 装饰器案例 code:

  • python-闭包和装饰器

    https://www.zhihu.com/question/25950466/answer/31731502 代...

  • python 高级 13闭包 装饰器

    闭包和装饰器 1.8 闭包和装饰器 学习目标 1. 能够说出闭包的定义形式 2. 能够说出装饰器的实现形式 ...

  • python-闭包

    函数里面的函数不被执行,返回了内部函数的引用。 ret(200), # 300传当前的值,可以计算 闭包的应用 如...

  • Python-闭包

    0. 函数相关知识 1)Python中“一切皆对象”,函数也不例外 先定义一个函数: def func(): p...

  • Python-闭包

    闭包的理解 我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值...

  • Python-闭包

    当函数调用完,函数内定义的,但是我们有时候需要,每次在这个变量的基础上完成一系列操作,比如:每次在这个变量的基础上...

  • 06.实现一个累加器

    使用构造函数和对象的方式,实现累加器:本质上还是闭包 使用闭包实现一个累加器闭包

  • 前端(数组,闭包,定时器)

    数组 定时器 定时器弹框 定时器的基本用法 定时器动画 闭包 闭包存循环的索引值 闭包做私有变量计数器 闭包做选项卡

  • Python装饰器-专题笔记

    学会装饰器,Python更进阶 函数作用域到闭包到装饰器讲解,及闭包和装饰器的运用。 [√] 慕课网Meshare...

网友评论

      本文标题:Python-闭包和修饰器

      本文链接:https://www.haomeiwen.com/subject/oyxikctx.html