装饰器的原则

1)不修改被修饰函数的源代码;

2)不修改被修饰函数的调用方式;

装饰器的知识点 = 高阶函数 + 函数嵌套 + 闭包

1. 只用高阶函数写装饰器--->有瑕疵

import time

def foo():
print('this is foo')
# return foo def timer(func):
starttime = time.time()
func()
stoptime = time.time()
print('使用的时间是:%s' %(stoptime - starttime))
return func foo = timer(foo)
foo() #执行结果是:
# this is foo
# 使用的时间是:0.00013685226440429688
# this is foo #多了一次执行结果

2. 闭包其实就是函数的嵌套

def First(name):
print('FirstLayer:%s' %name)
def Second():
name = 'bbb'
print('SecondLayer:%s' %name)
def Third():
name = 'ccc'
print('ThirdLayer:%s' %name)
Third()
Second()
First('aaa')

3. 函数闭包装饰器基本实现

# 实现阶段1:只需要在原来函数调用之前进行赋值操作。
import time def timer(func): #func == test
def good():
starttime = time.time()
func()
stoptime = time.time()
print('程序消耗的时间是:%s' %(stoptime - starttime))
return good def test():
print('这是test函数') test = timer(test) #此处函数运行的结果是return的good,可以看下一步证实。
print(timer(test)) #<function timer.<locals>.good at 0x10e3cb700>,因此需要下一步运行返回值函数good。
test() #test = good
# 实现阶段2:通过语法糖改进后,完全不需要动原来函数;
import time def timer(func): #func == test
def good():
starttime = time.time()
func()
stoptime = time.time()
print('程序消耗的时间是:%s' %(stoptime - starttime))
return good @timer #@timer 相当于 test = timer(test) def test():
print('这是test函数')
test()
# 实现阶段3:如何打印出真正test的返回值
import time def timer(func): #func == test
def good():
starttime = time.time()
res = func() #就是在运行test()
stoptime = time.time()
print('程序消耗的时间是:%s' %(stoptime - starttime))
return res
return good @timer #@timer 相当于 test = timer(test) def test():
print('这是test函数')
return '这是test的返回值'
ras = test()
print(ras)
# 阶段4装饰器适用于不同参数个数的函数
import time def timer(func): #func == test
def good(*args,**kwargs):
starttime = time.time()
res = func(*args,**kwargs) #就是在运行test()
stoptime = time.time()
print('程序消耗的时间是:%s' %(stoptime - starttime))
return res
return good @timer #@timer 相当于 test = timer(test) def test(name,age,gender):
print('这是test函数,名字是%s,年龄是%s,性别是%s' %(name,age,gender))
return '这是test的返回值'
ras = test('aaa','','male')
print(ras) @timer #@timer 相当于 test1 = timer(test1)
def test1(name,age,gender,hight):
print('这是test1函数,,名字是%s,年龄是%s,性别是%s,身高是%s' %(name,age,gender,hight))
return '这是test1的返回值'
ras = test1('bbb','','male','')
print(ras) # 如下为返回结果:
# 这是test函数,名字是aaa,年龄是18,性别是male
# 程序消耗的时间是:8.0108642578125e-05
# 这是test的返回值
# 这是test1函数,,名字是bbb,年龄是20,性别是male,身高是175
# 程序消耗的时间是:1.0013580322265625e-05
# 这是test1的返回值

4. 解压序列补充

# 使用解压序列取列表中的最开头和最结尾的值,可灵活使用。
>>> l = [1,2,3,4,5,6]
>>> a,*_,b = l
>>> l
[1, 2, 3, 4, 5, 6]
>>> a
1
>>> b
6
>>> a,*b,c = l
>>> a
1
>>> b
[2, 3, 4, 5]
>>> c
6
#快速交换两个变量的值
>>> f1,f2 = 1,2
>>> f1
1
>>> f2
2
>>> f1,f2 = f2,f1
>>> f1
2
>>> f2
1

5. 终极版装饰器-带参数验证功能的装饰器

user_list=[
{'name':'alex','passwd':''},
{'name':'linhaifeng','passwd':''},
{'name':'wupeiqi','passwd':''},
{'name':'yuanhao','passwd':''},
]
current_dic={'username':None,'login':False} def auth(auth_type='filedb'):
def auth_func(func):
def wrapper(*args,**kwargs):
print('认证类型是',auth_type)
if auth_type == 'filedb':
if current_dic['username'] and current_dic['login']:
res = func(*args, **kwargs)
return res
username=input('用户名:').strip()
passwd=input('密码:').strip()
for user_dic in user_list:
if username == user_dic['name'] and passwd == user_dic['passwd']:
current_dic['username']=username
current_dic['login']=True
res = func(*args, **kwargs)
return res
else:
print('用户名或者密码错误')
elif auth_type == 'ldap':
print('鬼才特么会玩')
res = func(*args, **kwargs)
return res
else:
print('鬼才知道你用的什么认证方式')
res = func(*args, **kwargs)
return res return wrapper
return auth_func @auth(auth_type='filedb') #auth_func=auth(auth_type='filedb')-->@auth_func 附加了一个auth_type --->index=auth_func(index)
def index():
print('欢迎来到京东主页') @auth(auth_type='ldap')
def home(name):
print('欢迎回家%s' %name)
#
@auth(auth_type='sssssss')
def shopping_car(name):
print('%s的购物车里有[%s,%s,%s]' %(name,'奶茶','妹妹','娃娃')) # print('before-->',current_dic)
# index()
# print('after--->',current_dic)
# home('产品经理')
shopping_car('产品经理')

Python函数装饰器的更多相关文章

  1. Python函数装饰器原理与用法详解《摘》

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...

  2. python函数-装饰器

    python函数-装饰器 1.装饰器的原则--开放封闭原则 开放:对于添加新功能是开放的 封闭:对于修改原功能是封闭的 2.装饰器的作用 在不更改原函数调用方式的前提下对原函数添加新功能 3.装饰器的 ...

  3. Python函数装饰器高级用法

    在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...

  4. Python 函数装饰器

    首次接触到装饰器的概念,太菜啦! Python 装饰器可以大大节省代码的编写量,提升代码的重复使用率.函数装饰器其本质也是一个函数,我们可以把它理解为函数中定义了一个子函数. 例如我们有这么一个需求, ...

  5. Python @函数装饰器及用法

    1.函数装饰器的工作原理 函数装饰器的工作原理是怎样的呢?假设用 funA() 函数装饰器去装饰 funB() 函数,如下所示: #funA 作为装饰器函数 def funA(fn): #... fn ...

  6. Python @函数装饰器及用法(超级详细)

    函数装饰器的工作原理是怎样的呢?假设用 funA() 函数装饰器去装饰 funB() 函数,如下所示: #funA 作为装饰器函数 def funA(fn): #... fn() # 执行传入的fn参 ...

  7. Python高手之路【四】python函数装饰器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

  8. python 函数 装饰器 内置函数

    函数 装饰器 内置函数 一.命名空间和作用域 二.装饰器 1.无参数 2.函数有参数 3.函数动态参数 4.装饰器参数 三.内置函数 salaries={ 'egon':3000, 'alex':10 ...

  9. Python 函数装饰器简明教程

    定义类的静态方法时,就使用了装饰器.其实面向对象中的静态方法都是使用了装饰器. @staticmethod def jump(): print(" 3 meters high") ...

  10. Python高手之路【四】python函数装饰器,迭代器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

随机推荐

  1. 幸存者偏差Survivorship Bias

    "最不符合逻辑的地方,一定埋藏着最深刻的逻辑."——余秋雨<行者无疆> 为什么要说幸存者偏差? 因为2018年全国II卷的描述即为典型的“幸存者偏差”,且这一例子被引入 ...

  2. PaddleBook的部署安全性问题

    作为一个学习paddle的新手,按照官方流程全套走一波是很有必要的. 按照官方的推荐,首先得安装一个PaddleBook. 然而,我在自己vps上安装好后,输入 http://myvps:8888,直 ...

  3. Django-1.10支持中文用户注册登录

    让django 支持中文注册登录,支持中文用户名cat django的models文件发现调的如下两个类 class AbstractUser(AbstractBaseUser, Permission ...

  4. ibtmp1文件过大

    有个数据库发现磁盘告警 已经100% 经过排查发现数据库的data目录下有个 ibtmp1是个什么东西呢?查看官方文档后发现 The temporary tablespace is a tablesp ...

  5. Oracle 重启监听

    对于DBA来说,启动和关闭oracle监听器是很基础的任务,但是Linux系统管理员或者程序员有时也需要在开发数据库中做一些基本的DBA操作,因此了解一些基本的管理操作对他们来说很重要. 本文将讨论用 ...

  6. css横竖屏适配

    Css做到横竖屏适配:定义两个样式 { @media screen and (orientation: portrait){ Css[竖向定义样式] } @media screen and (orie ...

  7. windows下python3使用pip安装scrapy提示安装失败

    我的环境:     python3.6,     win10,      原因:不能成功安装twisted,因为twisted与高版本的python有兼容问题. 解决:1,先下载twisted二进制文 ...

  8. 聊聊GIS中的坐标系|再版 详细定义、计算及高程系统

    本篇讲坐标系统的详细定义,有关坐标系的变换公式,以及简单说说高程坐标系统. 本文约6000字,阅读时间建议45分钟.硬内容比较多,如有疏漏错误请指出,建议有兴趣的朋友进一步阅读. 作者:博客园/B站/ ...

  9. RadioButton改写的开关按钮

    先上效果图: 这个控件其实是俩个RadioButton,通过样式就可以实现. 样式资源: <Style x:Key="Tong_Yong_RadioButtonStyle" ...

  10. nuget打包上传

    准备工作 下载nuget.exe,以及gui推送编辑工具 Nuget Package Explorer (可选) 设置nuget环境变量. 流程 完成项目 cmd控制台cd到项目目录下(项目目录不是解 ...