Python函数07/有参装饰器/多个装饰器装饰一个函数
Python函数07/有参装饰器/多个装饰器装饰一个函数
内容大纲
1.有参装饰器
2.多个装饰器装饰一个函数
1.有参装饰器
# def auth(argv):
# def wrapper(func):
# def inner(*args,**kwargs):
# func(*args,**kwargs)
# return inner
# return wrapper
# login_dic = {
# "username": None,
# "flag": False
# }
# def auth(argv): # argv == foo
# def wrapper(func):
# def inner(*args,**kwargs):
# if login_dic["flag"]:
# func(*args,**kwargs)
# else:
# if argv == "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 == "微信":
# 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 == "抖音":
# 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:
# 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 # foo = auth(foo)
# def foo():
# print("这是一个被装饰的函数")
#
# foo()
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("QQ")
def foo():
print("这是一个被装饰的函数")
# wrapper = auth(chose)
# foo = wrapper(foo)
foo()
"""
# @auth(chose) 相等于以下两行代码的解构
# wrapper = auth(chose)
# foo = wrapper(foo)
"""
2.多个装饰器装饰一个函数
def wrapper1(func):
def inner1(*args,**kwargs):
print(1)
func(*args,**kwargs)
print(11)
return inner1
def wrapper2(func): # func == foo
def inner2(*args,**kwargs):
print(11)
func(*args, **kwargs)
print(22)
return inner2
def wrapper3(func):
def inner3(*args,**kwargs):
print(3)
func(*args, **kwargs)
print(33)
return inner3
# @wrapper1 # 1 11
# @wrapper3 # 3 33
# @wrapper2 # 8 22
# def foo():
# print(8)
# foo = wrapper2(foo) # foo == inner2
# foo = wrapper3(foo) # inner3 = wrapper3(inner2)
# foo = wrapper1(foo) # inner1 = wrapper1(inner3)
# foo() # inner1()
# foo = wrapper3(foo) # foo == inner3
# foo = wrapper2(foo) # foo = wrapper2(inner3) foo == inner2
# foo = wrapper1(foo) # foo = wrapper1(inner2)
被装饰的函数正上方有多个装饰器,先执行离被装饰函数最近的装饰器



3.今日总结
# 1.有参装饰器
# 在装饰器的基础上再套一层
# @auth("QQ")
# def foo():
# pass
# f = auth("qq")
# foo = f(foo)
# foo()
# 2.多个装饰器装饰一个函数
# def wrapper1(func):
# def inner1(*args,**kwargs):
# print(1)
# func(*args,**kwargs)
# print(11)
# return inner1
#
# def wrapper2(func): # func == foo
# def inner2(*args,**kwargs):
# func(*args, **kwargs)
# print(22)
# return inner2
#
# def wrapper3(func):
# def inner3(*args,**kwargs):
# print(3)
# func(*args, **kwargs)
# print(33)
# return inner3
# @wrapper1 # 1 11
# @wrapper3 # 3 33
# @wrapper2 # 8 22
# def foo():
# print(8)
先执行离被装饰的函数最近的语法糖
小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走
3.今日练习
1.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
# import time
# def wrapper(f):
# t = 0
# def inner(*args,**kwargs):
# nonlocal t
# if time.time()-t >= 10:
# t = time.time()
# f(*args,**kwargs)
# else:
# print("被限制了")
# return inner
# @wrapper
# def func():
# print("被装饰函数")
# while True:
# func()
# time.sleep(2)
# func()
# time.sleep(2)
# func()
# time.sleep(2)
#
# 2.请写出下列代码片段的输出结果:
# def say_hi(func):
# def wrapper(*args,**kwargs):
# print("HI")
# ret=func(*args,**kwargs)
# print("BYE")
# return ret
# return wrapper
#
# def say_yo(func):
# def wrapper(*args,**kwargs):
# print("Yo")
# return func(*args,**kwargs)
# return wrapper
# @say_hi
# @say_yo
# def func():
# print("ROCK&ROLL")
# func()
# HI
# Yo
# ROCK&ROLL
# BYE
#
3.编写装饰器完成下列需求:
# 用户有两套账号密码,一套为京东账号密码,一套为淘宝账号密码分别保存在两个文件中。
# 设置四个函数,分别代表 京东首页,京东超市,淘宝首页,淘宝超市。
# 启动程序后,呈现用户的选项为:
# 1,京东首页
# 2,京东超市
# 3,淘宝首页
# 4,淘宝超市
# 5,退出程序
# 四个函数都加上认证功能,用户可任意选择,用户选择京东超市或者京东首页,只要输入一次京东账号和密码并成功,
# 则这两个函数都可以任意访问;用户选择淘宝超市或者淘宝首页,只要输入一次淘宝账号和密码并成功,则这两个函数都可以任意访问.
# 相关提示:用带参数的装饰器。装饰器内部加入判断,验证不同的账户密码。
# msg = """
# 1,京东首页
# 2,京东超市
# 3,淘宝首页
# 4,淘宝超市
# 5,退出程序
# 请选择序号>>>:
# """
# login_dic = {
# "jd":False,
# "tb":False
# }
# def auth(argv):
# def wrapper(f):
# def inner(*args,**kwargs):
# if login_dic[argv]:
# f(*args,**kwargs)
# else:
# print(f"{argv} login")
# user = input("请输入姓名:")
# psd = input("请输入密码:")
# with open(argv,"r",encoding="utf-8") as f1:
# for i in f1:
# username,password = i.strip().split(":")
# if user == username and psd == password:
# login_dic[argv] = True
# print("登录成功!")
# return f(*args,**kwargs)
# else:
# print("账号或密码错误")
# return inner()
# return inner
# return wrapper
#
# @auth("jd")
# def jd_index():
# print("这是京东主页")
#
# @auth("jd")
# def jd_shopping():
# print("这是京东超市")
#
# @auth("tb")
# def tb_index():
# print("这是淘宝主页")
#
# @auth("tb")
# def tb_shopping():
# print("这是淘宝超市")
#
# dic = {"1":jd_index ,"2":jd_shopping ,"3":tb_index,"4":tb_shopping, "5":exit}
# while True:
# choose = input(msg)
# if choose in dic:
# dic[choose]()
# else:
# print("请正确输入")
#
4.给l1 = [1,1,2,2,3,3,6,6,5,5,2,2]去重,不能使用set集合(面试题)。
# l1 = [1,1,2,2,3,3,6,6,5,5,2,2]
# lst = []
# for i in l1:
# if i not in lst:
# lst.append(i)
# print(lst)
#
5.用递归函数完成斐波那契数列(面试题):
# 斐波那契数列:1,1,2,3,5,8,13,21..........(第三个数为前两个数的和,但是最开始的1,1是特殊情况,可以单独讨论)
# lst = []
# def func(num):
# if num == 0:
# ret = 1
# elif num == 1:
# ret =1
# else:
# ret = (func(num-2)+func(num-1))
# return ret
# num = int(input(">>>"))
# n = 0
# while func(n) < num:
# lst.append(func(n))
# n += 1
# print(lst)
6.用户输入序号获取对应的斐波那契数字:比如输入6,返回的结果为8.
# def func(num):
# if num == 0:
# ret = 1
# elif num == 1:
# ret =1
# else:
# ret = (func(num-2)+func(num-1))
# return ret
# print(func(5))
7.请实现一个装饰器,限制该函数被调用的频率,如10秒一次(面试题)
# import time
# def wrapper(f):
# t = 0
# def inner(*args,**kwargs):
# nonlocal t
# if time.time()-t >= 10:
# t = time.time()
# f()
# else:
# print("被限制了")
# return inner
# @wrapper
# def func():
# print("被装饰函数")
# func()
Python函数07/有参装饰器/多个装饰器装饰一个函数的更多相关文章
- 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。
题目: 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数. 思路: 假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢? 解法 ...
- python进阶04 装饰器、描述器、常用内置装饰器
python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...
- Python全栈工程师(函数的传参)
ParisGabriel 感谢 大家的支持 每天坚持 一天一篇 点个订 ...
- Python笔记_第四篇_高阶编程_高阶函数_1.map和reduce
1. map()函数: 原型:map(fn,lsd) 参数1是函数 参数2是序列 功能:将传入的函数一次作用在序列中的每一个元素.并把结果作为一个新的Iterator返回.其实map函数就是一个for ...
- Python定义一个函数
Python函数:实现某种功能的代码段 定义一个函数需要遵循的规则: 1.使用 def 关键字 函数名和( ),括号内可以有形参 匿名函数使用 lambda 关键字定义 2.任何传入参数和自变量必须放 ...
- js中如何在一个函数里面执行另一个函数
1.js中如何在函数a里面执行函数b function a(参数c){ b(); } function b(参数c){ } 方法2: <script type="text/javasc ...
- js new一个函数和直接调用函数的区别
用new和调用一个函数的区别:如果函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象,而如果这个函数的返回值是一个引用类型(Object.Arr ...
- js new一个函数和直接调用函数的差别
用new和调用一个函数的差别:假设函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象.而假设这个函数的返回值是一个引用类型(Object.Arr ...
- vue中data必须是一个函数
前端面试时经常被问到:“组建中data为什么是函数”? 答案就是:在组件中data必须是一个函数,这样的话,每个实例可以维护一份被返回对象的独立拷贝.
随机推荐
- LNMP 环境更换Nginx 服务器为Tengine
本人之前所使用 LNMP 环境一直是原生的Nginx服务器,最近几天看了好多大网站使用 淘宝团队基于Nginx开发的 Tengine 决定给自己的虚拟机也装个玩玩. 关于Tengine的介绍就不多说了 ...
- Java | 静态嵌套类(Static Nested Class)
前言 本文内容主要来自 Java 官方教程中的<嵌套类>章节. 本文提供的是 JDK 14 的示例代码. 定义 静态嵌套类(Static Nested Class),是 Java 中对类的 ...
- JavaWeb网上图书商城完整项目--过滤器解决中文乱码
我们知道,如果是POST请求,我们需要调用request.setCharacterEncoding(“utf-8”)方法来设计编码:如果是GET请求,我们需要自己手动来处理编码问题.如果我们使用了En ...
- Python-argparse模块-获取命令行参数
#!/usr/bin/python3 """ Author : Jet Bi License : www.cyeap.com Summary : 获取命令行的参数 Not ...
- JAVA设计模式 3【创建型】理解工厂模式与抽象工厂模式
上一节我们已经学习了原型模式,稍微复习一下:通过重写Object 类的clone() 方法实现浅克隆,浅克隆也要实现Cloneable 标记接口.而深克隆则是将对象通过序列化和反序列化 的方式进行创建 ...
- 入门大数据---HDFS-API
第一步:创建一个新的项目 并导入需要的jar包 公共核心包 公共依赖包 hdfs核心包 hdfs依赖包 第二步:将Linux中hadoop的配置文件拷贝到项目的src目录下 第三步:配置windows ...
- 只需几行 JavaScript 代码,网页瞬间有气质了!
最近在网上闲逛,发现一个特别好玩的 JavaScript 库,叫 RoughNotation.干嘛用的呢?就是在网页上给文字加标注,比如下划线.方框.高亮文字背景等,不过是手写风格的!截图给大家感受下 ...
- Azure Monitor(二)Log Analytics
一,引言( 前情回顾) Azure Monitor 包括 Log Analytics 和 Application Insights,其提供的高级工具适用于收集和分析遥测数据,以便最大程度地提高云和本地 ...
- 【反转开灯问题】Face The Right Way
题目 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing forward, ...
- 泛型<T>,是你肿莫了,还是我错了...
委托自定义数组排序 项目一共三个文件如下. CSort.cs using System; using System.Collections.Generic; using System.Linq; us ...