装饰器

Posted sunj-96

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器相关的知识,希望对你有一定的参考价值。

一个完整的程序需要一个团队很多人的努力,当你的上一位程序员发给你一段没有问题的代码时,你要在这段代码的基础上添加功能,而且要遵循一个原则----开放-封闭原则。

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

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

假如,现在已经有了一段上一位程序员写好的代码

def jap():
    print("----日韩专区----")

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

def homemade():
    print("----国产专区----")

def cartoon():
    print("----动漫专区----")

现在因为日韩和国产的访问量较大,需要用户登录才能继续观看,所以要做到一下功能:

1.点击日韩或国产需要进入登录界面。

2.进入日韩会弹出登录界面,再进入国产显示登录成功不需要再登录,反之亦然。

 

你这样写代码可以实现这个功能:

user_state = False
name = "sunjing"
password = "123"
def login():
global user_state
if user_state == False:
user_name = input("name:")
user_password = input("password:")
if user_name == name and user_password == password:
print("login success")
user_state = True
else:
print("wrong name or password")
if user_state:
print("login success")
def jap():
login()
print("----日韩专区----")

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

def homemade():
login()
print("----国产专区----")

def cartoon():
print("----动漫专区----")

jap()      
homemade()

结果:

name:sunjing
password:123
login success
login success
----日韩专区----
login success
----国产专区----

发现调用jap()后再调用homemade()就不用再登陆了,实现了预想的功能,但是违反了不修改原来代码的原则于是再对程序进行修改

user_state = False
name = "sunjing"
password = "123"
def login(func):
    global user_state
    if user_state == False:
        user_name = input("name:")
        user_password = input("password:")
        if user_name == name and user_password == password:
            print("login success")
            user_state = True
        else:
            print("wrong name or password")
    if user_state:
        print("login success")
def jap():
    print("----日韩专区----")

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

def homemade():
    print("----国产专区----")

def cartoon():
    print("----动漫专区----")

jap = login(jap)
homemade = login(homemade)

结果:

name:sunjing
password:123
login success
login success
login success

修改后程序能实现上述功能但是发现没有调用函数,函数却自己运行了,而且改变了原来函数jap()的调用方式,所以这种方式还是不对,但是可以在上述代码的基础上加以修改

user_state = False
name = "sunjing"
password = "123"
def login(func):
    def inner():
        global user_state
        if user_state == False:
            user_name = input("name:")
            user_password = input("password:")
            if user_name == name and user_password == password:
                print("login success")
                user_state = True
            else:
                print("wrong name or password")
        if user_state:
            func()
            print("login success")
    return inner
def jap():
    print("----日韩专区----")

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

def homemade():
    print("----国产专区----")

def cartoon():
    print("----动漫专区----")

jap = login(jap)            #把jap当做一个参数传给login,此时login(jap)就是inner函数的内存地址,再把内存地址赋给jap
homemade = login(homemade)  

jap()                       #jap()相当于调用inner()
homemade()

这样就实现了不修改源程序,不修改调用方式,通过扩展的方式实现了要求的功能。该程序还可以通过别的方式化简:

user_state = False
name = "sunjing"
password = "123"

def login(func1):
    def inner():
        global user_state
        if user_state == False:
            user_name = input("name:")
            user_password = input("password:")
            if user_name == name and user_password == password:
                print("login success")
                user_state = True
            else:
                print("wrong name or password")
        if user_state == True:
            func1()
    return inner
@login                #相当于把@login下面的函数当做参数传入login()函数中,变成login(jap),再把login(jap)变成新函数执行
def jap():
    print("----日韩专区----")

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

@login                #@login就相当于jap = login(jap) == inner
def homemade(): print("----国产专区----")

def cartoon():
    print("----动漫专区----")

这就是装饰器的原理

 

 

 

 

 

 

 

 

 

 

 


 

以上是关于装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象学习之八,装饰器

thymeleaf 片段渲染后重新加载 javascript

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码