装饰器二次学习

直接改变模块里面函数的功能,将login() 引入到已经实现代码功能的模块里,不符合开放封闭原则。

user_status = False    #全局变量user_status,默认为False,如果用户登录成功,则修改为True,不用再登录。
def login():
    user = "alex"
    password = "123"
    global user_status   #这样就可以修改全局变量

    if user_status == False:  # 如果用户处于未登陆的状况,让用户进行登录。
        user = input("用户名:")
        password = input("密码:")
        if user == "alex"and password == "123":
            print("欢迎登陆")
            user_status = True
        else:
            print("您输的密码不正确,请重新输入")

    else:
        print("用户已登录,验证通过")


def home():
    print("----主页----")
def america():
    login()
    print("----欧美专区----")    #需要登录才能进入进入欧美专区
def japan():
    print("----日本专区----")
def henan():
    login()    #不符合开发的开放-封闭原则。封闭:已经实现功能的代码块不能被修改。开放:代码块只能被扩展。
    print("----河南专区----")

 已经实现功能的代码块,只能被扩展,不能被修改。下面的代码实现了扩展,也实现了功能。但是还是存在着问题。

    下面的代码改变了调用方式,用login调用henan等,如果存在多个模块,且别人用其他方式调用了河南,那么就需要全部修改为用login调用。

user_status = False


def login(func):   #将func函数作为参数传入到login
    user = "alex"
    password = "123"
    global user_status
    if not user_status:
        user = input("用户名:")
        password = input("密码:")
        if user == "alex"and password == "123":
            print("欢迎登陆")
            user_status = True
        else:
            print("您输入的密码错误,请重新输入")

    if user_status:   #用户已经登录则执行func
        func()


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


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


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


def henan():
    print("----河南专区----")

login(henan)

 login里嵌套一个inner函数,并且返回inner函数的地址。这样就不会直接执行login() 

user_status = False


def login(func):   #func是要传入的函数的内存地址

    def inner():
        user = "alex"
        password = "123"
        global user_status
        if not user_status:
            user = input("用户名:")
            password = input("密码:")
            if user == "alex"and password == "123":
                print("欢迎登陆")
                user_status = True
            else:
                print("您输入的密码错误,请重新输入")

        if user_status:
            func()     #执行执行要传入的函数。
    return inner



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


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


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


def henan():
    print("----河南专区----")


henan = login(henan) #赋值操作从右到左,执行login时先将 原henan当参数带入,并且最后返回inner,也就是新henan(新henan其实就是inner的内存地址)。
henan()        在原henan带入到login时,已经将原henan封包了,这样henan调用时最后的结果还是原henan。

 装饰器:在符合开放—封闭原则的同时,给代码添加新功能。

user_status = False


def login(func):   #func是要传入的函数的内存地址

    def inner():
        user = "alex"
        password = "123"
        global user_status
        if not user_status:
            user = input("用户名:")
            password = input("密码:")
            if user == "alex"and password == "123":
                print("欢迎登陆")
                user_status = True
            else:
                print("您输入的密码错误,请重新输入")

        if user_status:
            func()     #执行执行要传入的函数。
    return inner



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


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

@login    #在需要调用的函数上面添加@login,login就会把该函数传入到形参。等同于 japan=login(japan)
def japan():
    print("----日本专区----")

@login
def henan():
    print("----河南专区----")


america()
henan()

  

 

 

原文地址:https://www.cnblogs.com/Roc-Atlantis/p/8617971.html