装饰器的原则

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. [REDIS 读书笔记]第一部分 数据结构与对象 跳跃表

    下面是跳跃表的基本原理,REDIS的实现大致相同 跳跃表的一个特点是,插入NODE是通过随机的方式来决定level的,比较奇特 下面是skipList的一个介绍,转载来的,源地址:http://ken ...

  2. golang 自定义结构体(与其他语言对象类似)

    /* 结构体变量: 结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存, 因此必须在定义结构体并实例化后才能使用结构体的字段. type 类型名 struct { 字段1 字 ...

  3. Rip 动态路由协议

            路由信息协议(RIP) 是内部网关协议IGP中最先得到广泛使用的协议.        Routing Information Protocol) RIP是一种分布式的基于距离矢量的路由 ...

  4. windows运行shell脚本

    1. 环境变量的理解:快速找到程序并执行,配置在path的目录下有系统环境和用户环境,配置在此的只要目录路径就好,在cmd输入名字就会去此路径找匹配程序执行 2. 将git安装目录下的....\Git ...

  5. css实现表单label文字两端对齐

    如图,在我们写页面的时候,经常遇到这种的情况,而需求是想让label文字两端对齐,我们来看看如何用css解决 /**css代码**/ ul li{ list-style: none; } .info- ...

  6. Idea操作ElasticSearch

    前提: 1.ES服务成功启动 2.node.js成功启动 一.创建索引库 1.目录展示 2.导入依赖 <dependency> <groupId>org.elasticsear ...

  7. C#后台异步消息队列实现

    简介 基于生产者消费者模式,我们可以开发出线程安全的异步消息队列. 知识储备 什么是生产者消费者模式? 为了方便理解,我们暂时将它理解为垃圾的产生到结束的过程. 简单来说,多住户产生垃圾(生产者)将垃 ...

  8. 万科A顺利出局,布局一心堂

    万科的这两日的走势还不错,今日冲高回落,顺利出局. 那么有选中了一只 股票    一心堂 资金量W    12 建仓价格    22.2 加仓系数    1.5 加仓间隔    1.50% 总盈利比  ...

  9. asp.net abp模块化开发之通用树2:设计思路及源码解析

    一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...

  10. 8组 上课啦(Class BUddy Pro)使用体验

    下载上课啦app 进入页面显示的是一个第1周的课表,和可以看到本周为第几周,点击周可以调整第几周显示课表 ,课表内容为整周内容,本周内容一目了然.点击右上角可以进入主设置页面,设置页面可以设置静音模式 ...