什么是装饰器
#1 开放封闭原则:对扩展是开放的,对修改是封闭的
#2 装饰器本身可以是任意可调用对象,被装饰的对象也可以是任意可调用对象
#3 目的:
'''
在遵循
1. 不修改被装饰对象的源代码
2. 不修改被装饰对象的调用方式
原则下
为被装饰对象加上新功能
'''

1、函数名可以当作函数的参数

 import time
def timmer(func):
#函数名可以当做函数的参数
def inner():
start = time.time()
func()
end = time.time()
print(end - start)
return inner def hahaha():
time.sleep(0.1)
print('aaaa') hahaha() 输出结果
aaaa

2、假如我们不能修改这个函数的调用方式,也不能修改原代码,该怎么做到呢

 import time
def timmer(func):
#函数名可以当做函数的参数
def inner():
start = time.time()
func()
end = time.time()
print(end - start)
return inner def hahaha():
time.sleep(0.1)
print('aaaa') hahaha = timmer(hahaha) #timmer函数的地址给了hahaha 然后在进行调用
hahaha() aaaa
0.10033607482910156

# hahaha = timmer(hahaha) #timmer函数的地址给了hahaha
# hahaha() #实际上执行的是timmer

3、函数传参

 def timmer(func):  #---> hahaha
def inner(*args,**kwargs): #动态参数接收从kkk传来的1,2并进行压缩成元组
#args == (1,2) kwargs == {}
#*args == 1,2 **kwargs == a =1,b = 2
func(*args,**kwargs) # ---》kkk #func把值传给kkk并还原,实际上就是解压之前动态参数接收的压缩的值,返回给kkk函数
return inner def kkk(a,b):
print(a) kkk = timmer(kkk) #timmer函数里的func是kkk函数,然后返回inner函数给kkk
kkk(1,2) #kkk函数调用并传参给inner(动态参数*args), 1

参数
#实参:调用函数的时候传入的参数
#形参
#位置参数:必须传值

 def aaa(a,b):
print(a,b)
aaa(1,2)

#默认参数:可以不传

 def bbb(x=10):      #默认参数 没上传参数的话用默认的参数,上传的话会用上传的参数。
print(x)
bbb() #x = 10
bbb(20) #x = 20

#动态参数

 def ccc(*args):#1,2,3,4,5     #*args  会将ccc上传的参数以元组的方式存放
print(args) ccc(1,2,3,4,5)#按位置传参数

解压传参

 def ccc(*args):#1,2,3,4,5
print(args) #ccc(1,2,3,4,5)#按位置传参数 t = (1,2,3,4,5)
ccc(t) # ((1, 2, 3, 4, 5),)
ccc(*t) #(1, 2, 3, 4, 5) #解压

按关键字传参

 def ddd(**kwargs):   #kwargs接收传参然后以字典的方式存放
print(kwargs) ddd(k = 'a',j = 'b')#按关键字传参数

打散赋值

 def ccc(*args):
print('ccc:',args) #(1,2,3,4,5)
def inner(a,b,c,d,e):
print('inner',a,b,c,d,e)
inner(*args) #*(1,2,3,4,5) 打散 def inner(a,b,c,d,e): #接收解压的参数然后一一赋值
print('inner',a,b,c,d,e)
ccc(1,2,3,4,5)
inner(1,2,3,4,5)

4、语法糖

 def timmer(func):  #---> jjj
def inner(*args,**kwargs):
ret = func(*args,**kwargs) # --->ret = jjj()
print(ret)
return ret
return inner @timmer #jjj = timmer(jjj) 语法糖
def jjj():
return 123 jjj() #ret = jjj() 输出结果
123

5、装饰器函数

#装饰器的本质 :闭包函数
#功能:就是在不改变原函数调用方式的情况下,在这个函数前后加上扩展功能
def timmer(func):
def inner(*args,**kwargs):
'''添加函数调用之前的扩展代码'''
ret = func(*args,**kwargs)
'''添加函数调用之后的扩展代码'''
return ret
return inner
#设计模式 原则 开放封闭原则
#对扩展是开放的
#对修改是封闭的

6、装饰器装饰两个函数

 def wrapper(func):#装饰
def inner(*args,**kwargs): ret = func(*args,**kwargs) return ret
return inner @wrapper #aaa = wrapper(aaa)
def aaa():
print('asghksdlhf') @wrapper #bbb = wrapper(bbb)
def bbb():
print('asghksdlhf') aaa()
bbb() #输出结果:
#asghksdlhf
#asghksdlhf

7、有参装饰器

import time

def auth(auth_type): #auth_type='mysql'
def auth2(func):
def inner(*args,**kwargs):
if auth_type == 'file':
name=input('name:>> ')
pwd=input('password:>> ')
if name == 'egon' and pwd == '':
res=func(*args,**kwargs)
return res
else:
print('auth error')
elif auth_type == 'mysql':
print('mysql auth')
else:
print('not valid auth source')
return inner
return auth2 @auth(auth_type='mysql') #@auth2 #index=auth2(最原始的index) #index=inner
def index(name):
time.sleep(3)
print('welcome %s to index' %name) index('egon') #inner('egon')

python全栈开发从入门到放弃之装饰器函数的更多相关文章

  1. python全栈开发从入门到放弃之迭代器生成器

    1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable  可迭代的 可迭 ...

  2. python全栈开发从入门到放弃之面向对象的三大特性

    组合 class Course: def __init__(self,name,period,price): self.name = name self.period = period self.pr ...

  3. python全栈开发从入门到放弃之常用模块和正则

    什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.p ...

  4. python全栈开发从入门到放弃之模块和包

    一 模块 1 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编 ...

  5. python全栈开发从入门到放弃之socket网络编程基础

    网络编程基础 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务 ...

  6. python全栈开发从入门到放弃之递归函数的调用

    1.递归效率低,需要在进入下一次递归时保留当前的状态,见51cto博客 解决方法是尾递归,即在函数的最后一步(而非最后一行)调用自动但是python又没有尾递归,且对递归层级做了限制 必须有一个明确的 ...

  7. python全栈开发从入门到放弃之初识面向对象

    面向过程 VS 面向对象 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的复 ...

  8. python全栈开发从入门到放弃之socket并发编程多进程

    1.1 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程 ...

  9. python全栈开发从入门到放弃之socket并发编程多线程

    一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 二 开启线程的两种方式 from threadi ...

随机推荐

  1. 第二百四十八节,Bootstrap轮播插件

    Bootstrap轮播插件 学习要点: 1.轮播插件 本节课我们主要学习一下 Bootstrap 中的轮播插件. 一.轮播 轮播插件就是将几张同等大小的大图,按照顺序依次播放. 基本实例. 第一步,给 ...

  2. 遍历一个Set的方法只有一个:迭代器(interator)

    Set-HashSet实现类: 遍历一个Set的方法只有一个:迭代器(interator). HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复. 在O ...

  3. NYOJ 1009 So Easy[Ⅰ]【简单题】

    /* 题目大意:求三角形的外接圆 解题思路:c/sin(C)=2R,先求出cos,在求出sin 关键点:直接调用库 解题人:lingnichong 解题时间:2014-10-18 10:19:33 解 ...

  4. jQuery实现高亮显示网页关键词的方法

    本文实例讲述了jQuery实现高亮显示网页关键词的方法.分享给大家供大家参考.具体如下: 这是一款基于jquery实现的高亮显示网页上搜索关键词的代码,当你在文本框中输入的时候,如果下面的正文中包括你 ...

  5. phpcms v9表单实现问答咨询功能

    本文转自别人 phpcms v9的留言板插件可以安装留言板,做问答咨询,那样的话有很多东西需要修改,也有人发现phpcms v9有个表单向导功能,只能留言,不能回复,今天仿站网:新源网络工作室告诉大家 ...

  6. centos6安装系统时选包

    date: 2018-06-05   11:44:06 1,系统:minimal   2,包组:     Base System :  Base.Compatibility libraries.Deb ...

  7. 【BZOJ3442】学习小组 费用流

    [BZOJ3442]学习小组 Description [背景] 坑校准备鼓励学生参加学习小组. [描述] 共有n个学生,m个学习小组,每个学生有一定的喜好,只愿意参加其中的一些学习小组,但是校领导为学 ...

  8. mysql 修改默认配置 提高性能

    解决问题 Lost connection to MySQL server at ‘reading authorization packet’, system error: 0 通过修改 connect ...

  9. javascript自动识别是否移动设备访问

    代码 JavaScript | 复制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function is_pc(){     var os = new Array(& ...

  10. HDU 5701 中位数计数 百度之星初赛

    中位数计数 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...