~~函数进阶:装饰器~~

Posted jevious

tags:

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

进击のpython


函数进阶-装饰器


知道京东吧(不知道?那你知道淘宝,蘑菇街吧)

我们身为用户,在进入界面的时候

首先会提示我们登陆是吧

当我们登陆的时候,接下来的所有操作就不用再验证身份了

否则,一到收藏啊,关注啊,就需要我们重新登陆

那我们可不可以做一个这个呢??

没有数据库,我们模拟一个数据库,懂我意思吧!


DB = 
    "login": False,
    "user_name": "poddy",
    "password": "123546"


def login():
    if DB["login"] == False:
        usr = input("请输入用户名:")
        psd = input("请输入密码:")
        if usr == "poddy" and psd == "123546":
            print("登陆成功!")
            DB["login"] = True
        else:
            print("登录失败!")
            login()



def meizhuang():
    login(meizhuang)
    print("美妆专区")


def qinzi():
    login(qinzi)
    print("亲子专区")


def dianzi():
    login()
    print("电子专区")

dianzi()

这样,就完成了需求了

但是!!!!!!!!!!!!!!!!!!!!!!!

你改变了原来的写好的函数模块,你把每个模块都加上了login()函数

这样是不符合“开放-封闭”原则的(第一个原则!)

就是我现在实现的代码块(def里面包着的)你不能给我动

但是你可以给我加功能!


那就想到了函数的嵌套,将上一个函数当作参数传过来就完事了呗!

想的很好!于是进阶版来了!

DB = 
    "login": False,
    "user_name": "poddy",
    "password": "123546"


def login(func):
    if DB["login"] == False:
        usr = input("请输入用户名:")
        psd = input("请输入密码:")
        if usr == "poddy" and psd == "123546":
            print("登陆成功!")
            DB["login"] = True
            func()
        else:
            print("登录失败!")
            login(func)
    # if DB["login"] == True:
    #     func()


def meizhuang():
    print("美妆专区")


def qinzi():
    print("亲子专区")


def dianzi():
    print("电子专区")


login(dianzi)

OKOK,大功告成!

但是,还不行!!!!!!!!!!!!!!!!!!!!!!!!

你想想熬,你写的是函数是吧

原先调用函数是介个亚子

dianzi()

现在调用呢?就变成了这个亚子

login(dianzi)

一个人两个人好说,啊,改变一下调用方法

那要是很多人呢?你确定你还能活着出去?

调用方法也不能变!代码块也不能变!那要怎么做呢?


记得在匿名函数那提过,给匿名函数取名然后调用的问题

匿名函数不是函数嘛?那就是说明函数也是可以被命名的

这么解释有问题吗?

那我们是不是可以这么考虑

dianzi = login(dianzi)
dianzi()

执行一下,报错了!

为啥呢?仔细看一下,在执行 login(diazi) 的时候,按照代码逻辑,最后执行的是dianzi()

现在你将 login(diazi) 重命名为 dianzi , 然后执行dianzi()

那不就相当于你执行了 login(diazi)() 四舍五入最后你执行的就是 dianzi()()

dianzi()()??? 你见过这玩仍????


  • 装饰器

    这个问题是怎么解决的呢?

    DB = 
        "login": False,
        "user_name": "poddy",
        "password": "123546"
    
    
    def login(func):
        def inner():
            if DB["login"] == False:
                usr = input("请输入用户名:")
                psd = input("请输入密码:")
                if usr == "poddy" and psd == "123546":
                    print("登陆成功!")
                    DB["login"] = True
                    func()
                else:
                    print("登录失败!")
                    login(func)
    
        return inner
    
    
    def meizhuang():
        print("美妆专区")
    
    
    def qinzi():
        print("亲子专区")
    
    
    def dianzi():
        print("电子专区")
    
    
    dianzi = login(dianzi)
    
    dianzi()

    来吧,开始分析!

    技术图片

    通过闭包(野生程序员和科班程序员区别)和高阶函数,达到了效果

    而这个操作,就是装饰器

    当然,还有更简单的写法!

    DB = 
        "login": False,
        "user_name": "poddy",
        "password": "123546"
    
    
    def login(func):
        def inner():
            if DB["login"] == False:
                usr = input("请输入用户名:")
                psd = input("请输入密码:")
                if usr == "poddy" and psd == "123546":
                    print("登陆成功!")
                    DB["login"] = True
                    func()
                else:
                    print("登录失败!")
                    login(func)
    
        return inner
    
    
    @login
    def meizhuang():
        print("美妆专区")
    
    
    @login
    def qinzi():
        print("亲子专区")
    
    
    @login
    def dianzi():
        print("电子专区")
    
    
    dianzi()

  • 进阶

    我又有需求了!(这个人就是神经病!)

    那我想这样,我要是等级高,在电子区我就可以打折

    ┗|`O′|┛ 嗷~~简单,加个参数嘛!

    DB = 
        "login": False,
        "user_name": "poddy",
        "password": "123546"
    
    
    def login(func):
        def inner():
            if DB["login"] == False:
                usr = input("请输入用户名:")
                psd = input("请输入密码:")
                if usr == "poddy" and psd == "123546":
                    print("登陆成功!")
                    DB["login"] = True
                    func()
                else:
                    print("登录失败!")
                    login(func)
    
        return inner
    
    
    @login
    def meizhuang():
        print("美妆专区")
    
    
    @login
    def qinzi():
        print("亲子专区")
    
    
    @login
    def dianzi(vip):
        if vip >2:
            print("你可以打折")
        else:
            print("电子专区")
    
    
    dianzi(4)

    执行!报错!技术图片

    他说什么?inner() 里没有参数,但是我放进去了一个参数

    inner()?不应该是 dianzi() ?

    奥,才想起来,现在的 dianzi() 其实就是 inner()

    所以报错的是inner()

    缺参数是吧,那就加上被!

    DB = 
        "login": False,
        "user_name": "poddy",
        "password": "123546"
    
    
    def login(func):
        def inner(vip):
            if DB["login"] == False:
                usr = input("请输入用户名:")
                psd = input("请输入密码:")
                if usr == "poddy" and psd == "123546":
                    print("登陆成功!")
                    DB["login"] = True
                    func(vip)
                else:
                    print("登录失败!")
                    login(func)
    
        return inner
    
    
    @login
    def meizhuang():
        print("美妆专区")
    
    
    @login
    def qinzi():
        print("亲子专区")
    
    
    @login
    def dianzi(vip):
        if vip >2:
            print("你可以打折")
        else:
            print("电子专区")
    
    
    dianzi(4)

    执行!成功!技术图片

    完事了?并没有,当我加上一条这样的语句的时候

    meizhuang()

    这个错误又出现了!技术图片

    那我这个“美妆”版块,也不存在打折啊,我还能强行加个参数??

    想到了哪个知识点?对!参数里的非固定参数

    将代码修改一下:

    DB = 
        "login": False,
        "user_name": "poddy",
        "password": "123546"
    
    
    def login(func):
        def inner(*args,**kwargs):
            if DB["login"] == False:
                usr = input("请输入用户名:")
                psd = input("请输入密码:")
                if usr == "poddy" and psd == "123546":
                    print("登陆成功!")
                    DB["login"] = True
                    func(*args,**kwargs)
                else:
                    print("登录失败!")
                    login(func)
    
        return inner
    
    
    @login
    def meizhuang():
        print("美妆专区")
    
    
    @login
    def qinzi():
        print("亲子专区")
    
    
    @login
    def dianzi(vip):
        if vip >2:
            print("你可以打折")
        else:
            print("电子专区")
    
    
    dianzi(4)
    meizhuang()

    大功告成!装饰器其实就是这样的结构!!这个知识点很重要!!!

    最后再来个小题试试吧

    我想在电子专区加一个支付模块(print(“支付成功”)意思意思就行)

    怎么写呢?????????????????????????


*十分重要*
*值得深究*

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

python装饰器2:进阶

测开之函数进阶篇・第七篇《装饰器》

10-5装饰器进阶_带参数的装饰器多个装饰器装饰同一个函数

由浅入深,走进Python装饰器-----第二篇:进阶--函数装饰函数

python 基础篇 12 装饰器进阶

Python进阶----装饰器