25.装饰器

装饰器
原网站, 直接调用执行函数


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


def american():
    print("---欧美专区---")


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


def shanghai():
    print("---上海专区---")


#  需求::1,网址一开始免认证,上线功能,对日本和上海专区进行认证
account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login():
    if account["is_authenticated"] is False:
        username = input("user:")
        password = input("password:")
        if username == account["username"] and password == account["password"]:
            print("welcome to you ")
            account["is_authenticated"] = True
        else:
            print("wrong name or password")
    else:
        print("用户已经登陆成功")


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


def american():
    print("---欧美专区---")


def japan():
    login()  # 增加认证功能
    print("---日本专区---")


def shanghai():
    login()  # 增加认证功能
    print("---上海专区---")


home()
japan()
shanghai()
# 对日本和上海板块,增减login认证功能,但是违反了软件开发中"开放和封闭原则"---》不能改变源代码前提下增加新功能---方法不通


# 需求2,在不改变调用方式的情况下增加功能
account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login(func):
    if account["is_authenticated"] is False:
        username = input("user:")
        password = input("password:")
        if username == account["username"] and password == account["password"]:
            print("welcome to you ")
            account["is_authenticated"] = True
        else:
            print("wrong name or password")
    if account["is_authenticated"] is True:
        func()


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


def american():
    print("---欧美专区---")


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


def shanghai():
    print("---上海专区---")


home()
login(japan)
login(shanghai)

# 此方法,在没有修改源代码前提下,增加了新功能,但是,函数Japan和shanghang的调用方式发生变化,不是直接调用函数,而是当作参数传给了高阶函数,高阶函数内部调用。---方法不通


尝试不改变调用方式和不修改源代码继续修改,利用匿名函数
account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login(func):
    if account["is_authenticated"] is False:
        username = input("user:")
        password = input("password:")
        if username == account["username"] and password == account["password"]:
            print("welcome to you ")
            account["is_authenticated"] = True
        else:
            print("wrong name or password")
    if account["is_authenticated"] is True:
        func()


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


def american():
    print("---欧美专区---")


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


def shanghai():
    print("---上海专区---")


home()
janpan = login(japan)  # 类似匿名函数赋值,把login(japan)的执行结果赋值给新的变量Japan,与原函数名一致
shanghai = login(shanghai)
japan()
shanghai()
# 此方法,没有改变调用方式,没有改变源代码,但是,在还没有调用japan()和shanghai()的情况下。login(japan),login(shanghai)就已经调用了两个函数


# 利用函数嵌套和闭包,

account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login(func):
    def inner():
        if account["is_authenticated"] is False:
            username = input("user:")
            password = input("password:")
            if username == account["username"] and password == account["password"]:
                print("welcome to you ")
                account["is_authenticated"] = True
            else:
                print("wrong name or password")
        if account["is_authenticated"] is True:
            func()

    return inner  # 此时返回的是inner的内存地址,不执行


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


def american():
    print("---欧美专区---")


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


def shanghai():
    print("---上海专区---")


home()
janpan = login(japan)  # 执行login,传入参数,返回inner内嵌函数内存地址,return inner 地址
shanghai = login(shanghai)
japan()  # japan()-====》inner()执行Japan就相当执行inner()函数。执行inner函数,进而执行真正的japan函数.
shanghai()

# # 此方法,不改变调用方式,不改变源代码实现新功能
#

account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login(func):
    def inner():
        if account["is_authenticated"] is False:
            username = input("user:")
            password = input("password:")
            if username == account["username"] and password == account["password"]:
                print("welcome to you ")
                account["is_authenticated"] = True
            else:
                print("wrong name or password")
        if account["is_authenticated"] is True:
            func()

    return inner  # 此时返回的是inner的内存地址,不执行


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


def american():
    print("---欧美专区---")


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


@login
def shanghai():
    print("---上海专区---")


home()
# janpan=login(japan) #执行login,传入参数,返回inner内嵌函数内存地址,return inner 地址
# shanghai=login(shanghai)
japan()  # japan()-====》inner()执行Japan就相当执行inner()函数。执行inner函数,进而执行真正的japan函数.
shanghai()
# 使用语法糖装饰器


#需求,是对Japan和shanghai的vip等级做限制,只有在3级以上,才能使用
account = {
    "is_authenticated": False,
    "username": "caona",
    "password": "123"
}


def login(func):
    def inner(*args, **kwargs):
        if account["is_authenticated"] is False:
            username = input("user:")
            password = input("password:")
            if username == account["username"] and password == account["password"]:
                print("welcome to you ")
                account["is_authenticated"] = True
            else:
                print("wrong name or password")
        if account["is_authenticated"] is True:
            func(*args, **kwargs)

    return inner  # 此时返回的是inner的内存地址,不执行


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


def american():
    print("---欧美专区---")


@login
def japan(vip_level):
    if vip_level>3:
        print("---高端玩家专区---")
    else:
        print("---日本专区---")

@login#装饰器,语法糖
def shanghai(vip_level):
    if vip_level > 3:
        print("---高端玩家专区---")
    else:
        print("---上海专区---")


home()
japan(2)  # japan()-====》inner()执行Japan就相当执行inner()函数。执行inner函数,进而执行真正的japan函数.
shanghai(4)

 

posted @ 2019-09-22 18:30  派森716  阅读(146)  评论(0编辑  收藏  举报