Python—装饰器详解
装饰器:(语法糖)
嵌套函数 在一个函数的函数体内,用def声明一个新函数
def foo():
print('in the foo.')
def bar():
print('in the bar.')
bar() #要调用bar需要在在函数体内调用,类似局部变量
foo()
装饰器例子:仅针对注释的几段,对其进行排序,如下红字
import time #python的debug都是先读取最外层框架(最外层没有缩进),最外层中如果涉及到调用,再接着运行调用内容。 第一步 def timer(func): #当读取到 @timer的时候,相当于运行 test1 = timer(test1),所以会返回来读取 warpper 第三步
def warpper(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs) #此时才是真正意义上运行 test1函数 第六步
return func(*args,**kwargs) #保证fun()返回值也不变
stop_time = time.time()
print('in the test1() %s'%(stop_time-start_time))
return warpper #把test1当作实参传递给 timer,timer(test1),此时返回的是 函数warpper的内存地址 第四步 #然后此时运行到 python里的语法【@timer】
@timer #相当于 test1 = timer(test1),返回warpper的内存地址,此时如果运行 test1(),相当于 warpper(),warpper就开始执行其函数体内的语句 第二步
def test1():
time.sleep(1)
print('in the test1')
return ‘from test1’
test1() #此时运行的 test1()已经不是直接运行 test1函数了,是经过@timer,转换成运行 warpper()了 第五步
装饰器进阶版,装饰器本身带参数
user = 'gkx'
pass_1 = ''
def decorator(auth_type):
print("auth type",auth_type)
def outer_warpper(func):
def warpper(*args,**kwargs):
if auth_type == 'local':
username = input("id")
password = input("password")
if username == user and password == pass_1:
print('\033[32;1mwelcome\033[0m')
res = func(*args,**kwargs)
print("after decorator")
return res
else:
print('\033[31;1mwrong info\033[0m')
elif auth_type == 'ldap':
print('我不会')
return warpper
return outer_warpper #当访问到这里的返回值时候,会继续执行 warpper,然后执行逻辑就和上面提到的timer一样了 @decorator(auth_type='local') #这里分成两部分看,第一部分是 调用decorator(auth_type = 'local'),此时返回outer_wrapper的内存地址
#在第一部分的基础上,此时加上@,变成了 @outer_wrapper,相当于 homepage = outer_wrapper(wrapper),再返回了wrapper的内存地址 def homepage():
26 print('home page')
return 'from home' @decorator(auth_type='ldap')
def bbs():
print('in bbs') print(homepage())
bbs()
装饰器三个重要补充:
#一共有三个 # 第一个
from functools import wraps def outer(func):
@wraps(func) #wraps模块
def inner(*args,**kwargs):
print('装饰前')
ret = func(*args,**kwargs)
print('装饰后')
return ret
return inner @outer
def holiday(day):
''' :param day: days of vacation
:return:
'''
print("放假%s"%day)
return '好开心' print(holiday.__name__) #import wraps后此时打印holiday函数名,否则是 inner函数名
print(holiday.__doc__)
ret = holiday(3)
print(ret) # 第二个,当装饰器带参数
import time
FLAG = False
def out_timmer(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag:
start = time.time()
ret = func()
end = time.time()
print(start-end)
return ret
else:
ret = func()
return ret
return inner
return timmer
@out_timmer(FLAG) #可以看成两部 1, timmer = out_timmer(FLAG) 2, @timmer
def shop1():
time.sleep(0.01)
print('buy first thing') @out_timmer(FLAG)
def shop2():
time.sleep(0.01)
print('buy second thing') shop1()
shop2() #第三个 函数被多个装饰器调用
def wrapper1(func): #func-----> f
def inner1():
print('wrapper1,befor func')
ret = func()
print('wrapper1,after func') #这一句运行完,但是inner2还没结束,要返回inner2继续运行【print('wrapper2,after func')】
return ret
return inner1 def wrapper2(func): #func-----> inner1 inner1传给了wrapper2
def inner2():
print('wrapper2,befor func') #运行完这一句,下一句运行inner1,故返回到wrapper1继续运行
ret = func() #inner1
print('wrapper2,after func')
return ret
return inner2 @wrapper2 #wrapper1 执行完后,执行wrapper2 但是此时传入的不是f,是 inner1,相当于 wrapper(inner1) == inner2 然后继续运行warpper2
@wrapper1 #先执行到这里,因为语法糖要找离它最近的函数。wrapper2没找到,故往下运行。此时函数 f传给wrapper1 相当于 f = wrapper1(f) 即为 inner1
def f():
print('in the f')
f() #--------->>调用inner2
Python—装饰器详解的更多相关文章
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- Python中的各种装饰器详解
Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...
- Python全栈开发之8、装饰器详解
一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了.转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5486253.html 一.装饰器 装饰器可以使函数执 ...
- python函数装饰器详解
python装饰器(fuctional decorators)简单来说就是修改其他函数的函数. 这样的函数需要满足两个个条件: 1.不能修改原函数的源代码 2.不能改变原函数的调用方式 需要达到的效果 ...
- python之装饰器详解
这几天翻看python语法,看到装饰器这里着实卡了一阵,最初认为也就是个函数指针的用法,但仔细研究后发现,不止这么简单. 首先很多资料将装饰器定义为AOP的范畴,也就是Aspect Oriented ...
- python装饰器1:函数装饰器详解
装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函 ...
- python 叠加装饰器详解
def out1(func1): #7.func1=in2的内存地址,就是in2 print('out1') def in1(): #8.调用函数index() 因为函数在in1里,所以首先运行in1 ...
- (转)面向对象(深入)|python描述器详解
原文:https://zhuanlan.zhihu.com/p/32764345 https://www.cnblogs.com/aademeng/articles/7262645.html----- ...
随机推荐
- Python开发环境Linux配置
1. 在Windows下安装Linux的连接工具(XShell),选免费的 2.虚拟机安装,注意BIOS对虚拟机使用的设置(enable) 3.虚拟机安装好修改yum源(用阿里云的):https:// ...
- Session实现原理分析
http://www.jb51.net/article/77726.htm PHP第一次会话时会有Set-Cookie响应头返回,设置上PHPSESSID cookie Cache-Control: ...
- Mybatis经常被问到的面试题
1. #{}和${}的区别是什么? #{}是预编译处理,${}是字符串替换. Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值: ...
- python中使用os.path.join()
os.path.join的详细解释请移步os.path模块在使用的过程中,我使用如下代码: import ospath = "F:/gts/gtsdate/"b = os.path ...
- HDU 1260
Jesus, what a great movie! Thousands of people are rushing to the cinema. However, this is really a ...
- Axis2开发WebService客户端 的3种方式
Axis2开发WebService客户端 的3种方式 在dos命令下 wsdl2java -uri wsdl的地址(网络上或者本地) -p com.whir.ezoffi ...
- i2c状态机方法设计-verilog
2010-09-05 21:04:00 verilog语言基础学的差不多了.接着就是看看华为的语言编写规范.状态机设计方法是fpga的重要设计方法.所以我要记上一笔. 只要会FSM方法,用fpga编写 ...
- Collections.sort 的日期排序
public static void main(String[] args) throws ParseException { // sort降序排列 List<Date> dates = ...
- Linux firewalld 防火墙
Linux firewalld 防火墙 简介 RHEL 7 系统中集成了多款防火墙管理工具,其中 firewalld(Dynamic Firewall Manager of Linux system ...
- Oracle 11gR2 用户重命名(rename user)
Oracle 11.2.0.2里新增了一个新特性——用户重命名(Rename User),在这个版本之前要想重命名用户,需要按用户导出,再fromuser touser(imp)或remap_sc ...