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

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

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


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

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

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

时间: 2024-10-05 06:41:15

~~函数进阶(一):装饰器~~的相关文章

python开发函数进阶:装饰器

一,装饰器本质 闭包函数 功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能 二,设计模式 开放封闭原则 *对扩展是开放的 *对修改是封闭的 三,代码解释 1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 4 tag = False 5 6 def login(func): 7 def inner(*args,**kwargs): 8 global tag 9 if tag == False: 10 user = input('pl

Python - 函数进阶之装饰器

本章内容 高阶函数 装饰器 前言 接着上一篇函数进行整理.. 一.高阶函数 高阶函数就是将一个函数以参数的形式传入另一个函数 1 def main_func(func): 2 # 定义一个主函数,并设置一个参数func 3 4 return func 5 # 返回func的值,因为我需要传入一个函数,即返回func的返回值 6 7 def func(): 8 # 定义一个函数作为参数传入主函数 9 10 return "Lyon" 11 # 返回 "Lyon" 给f

函数进阶(装饰器)

装饰器 python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象(函数的指针).装饰器函数的外部函数传入我要装饰的函数名字,返回经过修饰后函数的名字:内层函数(闭包)负责修饰被修饰函数.从上面这段描述中我们需要记住装饰器的几点属性,以便后面能更好的理解: 实质: 是一个函数 参数:是你要装饰的函数名(并非函数调用) 返回:是装饰完的函数名(也非函数调用) 作用:为已经存在的对象添加额外的功能 特点:不需要对对象做任何的代码

Python进阶(六)----装饰器

Python进阶(六)----装饰器 一丶开放封闭原则 开放原则: ? 增加一些额外的新功能 封闭原则: ? 不改变源码.以及调用方式 二丶初识装饰器 装饰器: ? 也可称装饰器函数,诠释开放封闭原则,装饰器的本质是闭包 ###普通版装饰器 import time def timmer(x): # x 接收的原函数的内存地址 def inner(): start_time=time.time() x() # 执行 原函数 print(f'执行效率{time.time()-start_time}'

第四天 内置函数2 随机码 装饰器 迭代器、生成器 递归 冒泡算法 JSON

关于函数的return li = [11,22,33,44] def f1(arg): arg.append(55) li = f1(li) print(li) 因为li = f1(li) 实际赋值的是f1的return,那么在这种情况下函数f1并未定义return,所以默认返回None 因此li的值应该是none 如果是 li = [11,22,33,44] def f1(arg): arg.append(55) f1(li) print(li) 因为函数传递的参数实际是参数的引用,因此在函数

函数嵌套与装饰器

*应用场景,位置参数中代表将多个参数存入元祖,**将关键字参数传入字典 位置参数: 位置形参:必须被传值,一一对应 位置实参:按从左到右的顺序与形参一一对应 关键字参数:按照key=value形式指名道姓的为形参传值,可以完全不按照顺序 1.关键字实参必须在位置参数的后面 2.可以混用位置实参与关键字实参,但不能为同一个形参重复传值 默认参数: 形参有默认值 可变长参数 形参:*args,**kwargs将多余的参数分别封装成元祖与字典 实参:将args kwargs分别打散 什么是命名关键字参

Django视图函数函数之视图装饰器

FBV模式装饰器: 普通函数的装饰器(语法糖@) views.py 1 from django.shortcuts import render 2 3 def wrapper(f): 4 def inner(*args,**kwargs): 5 print("before") 6 ret=f(*args,**kwargs) 7 print("after") 8 return ret 9 return inner 10 11 @wrapper 12 def index

【Python基础】高阶函数+函数嵌套+闭包 ==装饰器

高阶函数+函数嵌套+闭包 == 装饰器 一 什么是装饰器 二 装饰器需要遵循的原则 三 实现装饰器知识储备 四 高阶函数 五 函数嵌套 六 闭包 七 无参装饰器 八 装饰器应用示例 九 超时装饰器 参考: https://www.cnblogs.com/linhaifeng/articles/6140395.html https://www.cnblogs.com/haiyan123/p/8387769.html 原文地址:https://www.cnblogs.com/XJT2018/p/11

python函数四(装饰器进阶)

一.开放封闭原则 1.对扩展是开放的 任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对修改是封闭的 比如我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户. 装饰器完美的遵循了开放封闭原则. 二.函数的有用信息 def func(): ''' 本函数主要用于绘图,实时接收数据 :return:返回给前端某标签 ''' print(func.__doc

python函数三 (装饰器)

一.函数名(学名:第一类对象) 函数名本质上就是函数的内存地址.通俗点就是特殊的普通变量 def func(): print(111) func() print(func) # 结果: # 111 # <function func at 0x00000150713F6048> 1.可以被引用(即可以赋值给其他变量) def func(): print('in func') f = func f() # 结果: # in func 2.可以被当作容器类型的元素 def func(): print