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/有参装饰器/多个装饰器装饰一个函数的更多相关文章

  1. 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数rand10(),该函数能够生成1-10的随机数。

    题目: 已知一个函数rand7()能够生成1-7的随机数,请给出一个函数,该函数能够生成1-10的随机数. 思路: 假如已知一个函数能够生成1-49的随机数,那么如何以此生成1-10的随机数呢? 解法 ...

  2. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  3. Python全栈工程师(函数的传参)

     ParisGabriel   感谢 大家的支持                                                               每天坚持 一天一篇 点个订 ...

  4. Python笔记_第四篇_高阶编程_高阶函数_1.map和reduce

    1. map()函数: 原型:map(fn,lsd) 参数1是函数 参数2是序列 功能:将传入的函数一次作用在序列中的每一个元素.并把结果作为一个新的Iterator返回.其实map函数就是一个for ...

  5. Python定义一个函数

    Python函数:实现某种功能的代码段 定义一个函数需要遵循的规则: 1.使用 def 关键字 函数名和( ),括号内可以有形参 匿名函数使用 lambda 关键字定义 2.任何传入参数和自变量必须放 ...

  6. js中如何在一个函数里面执行另一个函数

    1.js中如何在函数a里面执行函数b function a(参数c){ b(); } function b(参数c){ } 方法2: <script type="text/javasc ...

  7. js new一个函数和直接调用函数的区别

    用new和调用一个函数的区别:如果函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象,而如果这个函数的返回值是一个引用类型(Object.Arr ...

  8. js new一个函数和直接调用函数的差别

    用new和调用一个函数的差别:假设函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象.而假设这个函数的返回值是一个引用类型(Object.Arr ...

  9. vue中data必须是一个函数

    前端面试时经常被问到:“组建中data为什么是函数”? 答案就是:在组件中data必须是一个函数,这样的话,每个实例可以维护一份被返回对象的独立拷贝.

随机推荐

  1. postman切换环境

    原文链接:https://www.cnblogs.com/nicole-zhang/p/11498384.html 通常会有多个测试环境,针对同一个接口来说,可能只是域名有变化,此时可以添加postm ...

  2. FFT快速傅里叶变换的python实现

    FFT是DFT的高效算法,能够将时域信号转化到频域上,下面记录下一段用python实现的FFT代码. # encoding=utf-8 import numpy as np import pylab ...

  3. mysql常用基础指令大全

    mysql指令 启动 net start mysql 退出mysql quit 登录 mysql -uroot -p 逻辑非 not ! 逻辑与 and && 或者 or || 逻辑异 ...

  4. Activity学习笔记1

    Activity概述 简单的理解Activity就是指Android手机或平板的一个屏,类似Window的一个窗口,浏览器的一个页面. Activity的4种状态 Activity的生命周期 创建Ac ...

  5. navicat 出现 mysql远程连接问题 Lost connection to MySQL server at ‘reading initial communication packet', system error: 0

    今天做服务器上的东西需要看数据库时,突然发现有这个报错,然后自己也查了很多资料 我最后找到一个在my,cnf配置文件中mysqld下加入一条 max_allowed_packet = 500M 也就是 ...

  6. .Net Core Configuration Etcd数据源

    前言     .Net Core为我们提供了一套强大的Configuration配置系统,使用简单扩展性强.通过这套配置系统我们可以将Json.Xml.Ini等数据源加载到程序中,也可以自己扩展其他形 ...

  7. 漏洞复现-Office远程代码执行漏洞 (CVE-2017-11882&CVE-2018-0802)

    漏洞原理 这两个漏洞本质都是由Office默认安装的公式编辑器(EQNEDT32.EXE)引发的栈溢出漏洞(不要问什么是栈溢出,咱也解释不了/(ㄒoㄒ)/~~) 影响版本 Office 365 Mic ...

  8. selenium(3)-针对鼠标的操作

    背景 用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击.双击.点击鼠标右键.拖拽等等. 而selenium给我们提供了一个类来处理这类事件-----------Acti ...

  9. 这一次搞懂SpringBoot核心原理(自动配置、事件驱动、Condition)

    @ 目录 前言 正文 启动原理 事件驱动 自动配置原理 Condition注解原理 总结 前言 SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本 ...

  10. 【思考】URI和URL的区别?以及URL的结构

    URI = Universal Resource Identifier URL = Universal Resource Locator 在学习中,我们难免会遇到 URI 和 URL,有时候都傻傻分不 ...