码迷,mamicode.com
首页 > 其他好文 > 详细

~~函数进阶(一):装饰器~~

时间:2019-07-06 10:36:35      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:mamicode   vip   模拟   十分   成功   代码   京东   进阶   高阶函数   

进击の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(“支付成功”)意思意思就行)

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


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

~~函数进阶(一):装饰器~~

标签:mamicode   vip   模拟   十分   成功   代码   京东   进阶   高阶函数   

原文地址:https://www.cnblogs.com/jevious/p/11141776.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!