Python中装饰器语法初识,以及用到的高阶函数、闭包

'''
装饰器,闭包,高阶函数同时使用

'''

account = {
    'is_authenticated': False,    # 打开网站时默认用户未登录,用户登录成功则改成True
    'username':'alex',
    'password':'abc123'
}


# 定义一个登录函数
def login(func):   # func表示把一个函数当成参数再传给另一个函数


    def inner(*args,**kwargs):   # 在定义一层函数实现闭包,
        if account['is_authenticated'] is False:   # 判断用户没有登录,需要用户输入登录信息
            username = input('请输入您的账户:')
            password = input('请输入您的密码:')
            if username == account['username'] and password == account['password']:
                print('登录成功')
                account['is_authenticated'] = True
                func(*args,**kwargs)      # 认证成功,执行功能函数   func()就相当于执行功能america()函数
            else:
                print('用户名或者密码错误')
        else:
            print('用户已经登录,验证通过')
            func(*args,**kwargs)  # 认证成功,执行功能函数

    return inner     # 返回值是inner的内存地址,不执行函数


def home():
    print('----首页-----')

@login   # 装饰器语法
def america():
    # login()     # 执行前加上登录验证
    print('------欧美专区----------')


def japan():
    print('--------日本专区-----------')

@login    # 装饰器语法
def chinese(vip_level):
    # login()     # 执行前加上登录验证

    # 最后想再加一个功能,判断用户VIP等级
    if vip_level > 5:
        print('解锁本专区所有资源')
    else:
        print('中文专区普通资源')


home()
'''
如何在不违背软件开发中的“开发---封闭”基础上:实现在指定网站页面验证用户是否登录
    我只需要写个认证方法,每次调用需要验证的功能时,直接把这个功能的函数名当做一个参数传给我的验证模块即:使用高阶函数方法
'''
# login(america)   # 网站某某区的功能,需要验证用户登录与否,就直接调用login,把需要验证的功能当成一个参数传给login即可
# login(chinese)   # 改变了调用方式违背了开发---封闭原则

# america = login(america)   # 上面用到的@login 就不需要这两行代码了
# chinese = login(chinese)
'''
运行结果:下面两句代码会报错TypeError: 'NoneType' object is not callable 
    表示下面两个函数调用报错,因为他们两个此时是一个None.为什么、会是None了?
    因为当代码执行到america = login(america) ,就会执行函数america(),而执行这个功能时,我们没有返回任何值,如果再执行america(),就会报错
    要想避免这种问题:就需要用到闭包了
'''
america()  # 有了上面两句代码,我再写这两句代码,源代码的调用方式我就没有改变了
chinese(7)   # 有了上面的闭包现象,这行代码相当于执行inner()函数
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章