2. 带参数的装饰器

#在装饰器的基础上再套一层
def auth(argv):
def wrapper(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
return wrapper
@auth() # 可传参
def func():
pass
func()
#解开:
"""
wrapper = auth()
func = wrapper(func)
func()
"""
#示例:实现选择不同的登录方式
login_dic = {"username": None,"flag": False}
# 正确的案例
msg = """
QQ
微信
抖音
邮箱
请输入您要选择登陆的app:
"""
chose = input(msg).upper() def auth(argv):
def wrapper(func):
def inner(*args,**kwargs):
if login_dic["flag"]:
func(*args,**kwargs)
else:
if argv == "QQ":
print("欢迎登陆QQ")
user = input("username:")
pwd = input("password:")
if user == "alex" and pwd == "alex123": # qq
login_dic["flag"] = True
login_dic["username"] = user
func(*args,**kwargs)
else:
print("用户名或密码错误!")
elif argv == "微信":
print("欢迎登陆微信")
user = input("username:")
pwd = input("password:")
if user == "1351101501" and pwd == "alex": # 微信
login_dic["flag"] = True
login_dic["username"] = user
func(*args, **kwargs)
else:
print("用户名或密码错误!")
elif argv == "抖音":
print("来了,老弟!")
user = input("username:")
pwd = input("password:")
if user == "alexdsb" and pwd == "alex": # 抖音
login_dic["flag"] = True
login_dic["username"] = user
func(*args, **kwargs)
else:
print("用户名或密码错误!")
else:
print("欢迎登陆dab邮箱")
user = input("username:")
pwd = input("password:")
if user == "alexdsb@dsb.com" and pwd == "alex": # 邮箱
login_dic["flag"] = True
login_dic["username"] = user
func(*args, **kwargs)
else:
print("用户名或密码错误!") return inner
return wrapper
@auth(chose)
def foo():
print("这是一个被装饰的函数")
foo()
"""
# @auth(chose) 相等于以下两行代码的解构:
# wrapper = auth(chose)
# foo = wrapper(foo)
"""

3. 多个装饰器装饰一个函数

#先执行离被装饰的函数最近的语法糖。
#小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走。

def wrapper1(f):
def inner1(*args,**kwargs):
print("这是第一个函数的开始!")
f()
print("这是第一个函数的结束!")
return inner1
def wrapper2(f): # f = inner3
def inner2(*args,**kwargs):
print("这是第二个函数的开始!")
f()
print("这是第二个函数的结束!")
return inner2
def wrapper3(f):
def inner3(*args,**kwargs):
print("这是第三个函数的开始!")
f()
print("这是第三个函数的结束!")
return inner3
@wrapper1
@wrapper2
@wrapper3
def func():
print("这是被调用的函数!")
func() #解开:
#func = wrapper3(func) #func == inner3
#func = wrapper2(func) #func == wrapper2(inner3) func = inner2
#func = wrapper1(func) #func == wrapper1(inner2) func = inner1
#func() #inner1() """
这是第一个函数的开始!
这是第二个函数的开始!
这是第三个函数的开始!
这是被调用的函数!
这是第三个函数的结束!
这是第二个函数的结束!
这是第一个函数的结束!
"""

python 15 带参装饰器的更多相关文章

  1. Python中带参装饰器理解

  2. python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器

    复习 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.返回内部函数对象---->  延迟执行, 开放封闭原则: 功能可以拓展,但源代 ...

  3. python带参装饰器的改良版

    简单点就是这种 def deco2(param=1): def _deco2(fun): def __deco2(*args, **kwargs): print (param) fun(*args, ...

  4. python 带参与不带参装饰器的使用与流程分析/什么是装饰器/装饰器使用注意事项

    一.什么是装饰器 装饰器是用来给函数动态的添加功能的一种技术,属于一种语法糖.通俗一点讲就是:在不会影响原有函数的功能基础上,在原有函数的执行过程中额外的添加上另外一段处理逻辑 二.装饰器功能实现的技 ...

  5. 周末学习笔记——day02(带参装饰器,wraps修改文档注释,三元表达式,列表字典推导式,迭代器,生成器,枚举对象,递归)

    一,复习 ''' 1.函数的参数:实参与形参 形参:定义函数()中出现的参数 实参:调用函数()中出现的参数 形参拿到实参的值,如果整体赋值(自己改变存放值的地址),实参不会改变,(可变类型)如果修改 ...

  6. python14 1.带参装饰器 | wrapper 了了解 # 2.迭代器 ***** # 可迭代对象 # 迭代器对象 # for迭代器 # 枚举对象

    ## 复习 '''函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 ...

  7. day14 带参装饰器、迭代器、生成器

    """ 今日内容: 1.带参装饰器及warps 2.迭代器 3.生成器 """ """ # 一.带参装饰器及w ...

  8. day14带参装饰器,迭代器,可迭代对象 , 迭代器对象 ,for迭代器 , 枚举对象

    复习 ''' 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 装饰 ...

  9. day-14带参装饰器、迭代器

    带参装饰器 通常,装饰器为被装饰的函数添加新功能,需要外界的参数  -- outer参数固定一个,就是func -- inner参数固定同被装饰的函数,也不能添加新参数 -- 可以借助函数的嵌套定义, ...

随机推荐

  1. 深入理解Java中的锁(二)

    locks包结构层次 Lock 接口 方法签名 描述 void lock(); 获取锁(不死不休) boolean tryLock(); 获取锁(浅尝辄止) boolean tryLock(long ...

  2. python课堂整理14---函数式编程

    一.分类 当下主流的编程方法大体分为三类 1. 面向过程 2. 函数式 3. 面向对象 二.函数式编程:函数式 = 编程语言定义的函数 + 数学意义的函数 特征:1. 不可变数据 2. 第一类对象 3 ...

  3. python课堂整理4---列表的魔法

    一.list   类, 列表 li = [1, 12, 9, "age", ["大白", "小黑"], "alex"] ...

  4. 勘误:EOS资源抵押退还

    关键字:勘误,delegatebw,undelegatebw,listbw,资源管理,抵押,解抵押,返还资源 EOS中,资源抵押与解抵押是通过一对命令完成的:delegatebw,undelegate ...

  5. rabbitMQ_Publish/Subscribe(三)

    发布/订阅 生产者发布信息,多个订阅者可以同时接收到信息. 转发器 现在是时候在RabbitMQ中引入完整的消息传递模式了. 让我们快速了解我们在以前的教程中介绍的内容: 生产者是一个发送消息的应用程 ...

  6. IDEA自定义配置

    目录 1 常规设置 1 修改字体大小 2 创建文件时 增加注释信息 3 项目编码为UTF-8 4 properties 文件编码为UTF-8且Transparent native-to-ascii c ...

  7. BeanFactory体系结构

    BeanFactory是Spring中非常重要的一个类,搞懂了它,你就知道了bean的初始化和摧毁过程,对于深入理解IOC有很大的帮助. BeanFactory体系结构 首先看一下使用IDEA生成的继 ...

  8. Asp.Net Core 发布到 Docker(Linux Centos 虚拟机,使用Dockerfile)

    实践一下 Asp.Net Core (基于.net core 2.2)部署到Docker 一.准备工作: 1. 使用Virtualbox创建一个Centos系统的虚拟机,并安装docker和vim 2 ...

  9. python创建虚拟环境(Windows)

    >>>构建Python虚拟环境的目的是为了防止真实环境被破坏!!! >>>每一个项目建议用一个虚拟环境为了防止软件版本号冲突!!! 1.在终端切换到一个新的磁盘 如 ...

  10. ansible批量管理服务 下

    1 ansible-playbook 任务剧本 1.1 剧本文件概念 (1)playbook可以将多个批量操作模块功能整合,完成一件事情.(2)简化运维工作复杂度(3)playbook通过yaml语法 ...