函数进阶之装饰器

装饰器是python基础中的重点。

装饰器就是在符合开放封闭的原则下给你的代码加功能。其出现是为了遵循开放-封闭原则。

封闭:已实现的功能代码块不应该被修改。

开放:对现有功能的扩展开放。

示例:

user_status = False  # 用户登录了就把这个改成True


def login(func):  # 把要执行的模块从这里传进来
    def wrapper(*args,**kwargs):
        _username = "alex"  # 假装这是DB里存的用户信息
        _password = "123"  # 假装这是DB里存的用户信息
        global user_status

        if user_status == False:
            username = input("user:")
            password = input("pasword:")

            if username == _username and password == _password:
                print("welcome login....")
                user_status = True
            else:
                print("wrong username or password!")

        if user_status == True:
            func(*args,**kwargs)  # henan()

    return wrapper


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


def america():
    # login() #执行前加上验证
    print("----欧美专区----")


@login
def japan():
    print("----日韩专区----")


@login  # henan = login(henan),只要@了,不执行henan(),也会自动执行这段代码,前提是login必须是一个函数名。  #  返回wrapper的内存地址
def henan(style):
    print("----河南专区----", style)

henan('豫剧')

解析:henan = login(henan),是把henan当做参数传给了login。这时候,henan这个函数里的代码并没有执行,而是返回了wrapper, 当执行henan的时候等于是执行了wrapper,

wrapper里的代码是进行用户认证,如果认证通过就会执行func(),在这个例子里也就是henan(),而henan里的代码在内部已经封装到了上一层的局部变量里面,所以会去上一层找henan的代码执行(闭包)

装饰器带参数

@login返回wrapper的内存地址,执行henan('豫剧')也就是执行wrapper('豫剧'),所以wrapper定义的接收任何参数,验证成功后执行func('豫剧'),也就是执行henan('豫剧'),
'豫剧'是wrapper传的参数'。这里要用非固定参数,因为别的模块可能不传参数或者传多个参数。

装饰器带参数进阶

示例

# 允许用户选择用qqweiboweixin认

user_status = False  # 用户登录了就把这个改成True


def login(auth_type):  # 把要执行的模块从这里传进来
    def outer(func):  # henan
        def wrapper(*args, **kwargs):
            _username = "alex"  # 假装这是DB里存的用户信息
            _password = "123"  # 假装这是DB里存的用户信息
            global user_status

            if user_status == False:
                username = input("user:")
                password = input("pasword:")

                if username == _username and password == _password:
                    user_status = True
                else:
                    print("wrong username or password!")

            if user_status == True:
                print(auth_type, '登陆')
                func(*args, **kwargs)  # henan()

        return wrapper

    return outer


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


def america():
    # login() #执行前加上验证
    print("----欧美专区----")


# @login('weixin')
def japan():
    print("----日韩专区----")


'''
@login('qq')其实等于 henan = login('qq')(henan) = wrapper
 1.先执行login('qq'),返回outer 2.相当于这里赋的是@outer了,也就是henan=outer(henan),然后返回wrapper。
 这样执行henan()这个函数的时候,由于闭包原则,也可以使用login带的'qq'这个参数。
'''


@login('qq')
def henan(style):
    print("----河南专区----", style)

henan('豫剧')  # wrapper('豫剧')

参考:https://www.cnblogs.com/alex3714/articles/5765046.html

原文地址:https://www.cnblogs.com/lshedward/p/9970556.html