1. 本质就是一个函数,这个函数符合闭包语法结构,可以在函数不需要改变任何代码情况下增加额外功装饰器的返回值是一个函数的引用
  2. 功能:1.引入日志;2.函数执行时间统计;3.执行函数前预备处理;4.执行函数后清理功能;5.权限校验;6.缓存

作用域

x =
def funx():
x =
print(x)
funx()
print(x) x =
def funx():
print(x)
funx()
print(x) x =
def funx():
def func1():
print(x)
func1()
funx()
print(x)

输出


函数名作为返回值

def outer():
def inner():
pass
return inner s = outer()
print(s)

输出

<function outer.<locals>.inner at 0x1058c60d0>

函数名可以作为一个参数

def index():
print("index func") def outer(index):
s = index
s() outer(index)

输出

index func

code

def outer():
def inner():
print("inner func excuted")
inner() # 调用执行inner()函数
print("outer func excuted")
outer() # 调用执行outer函数

输出

inner func excuted
outer func excuted

code

x =
def outer(): def inner():
print("x=%s" %x) # 引用了一个非inner函数内部的变量
print("inner func excuted")
inner() # 执行inner函数
print("outer func excuted") outer()

输出

x=
inner func excuted
outer func excuted

code

def outer():
x =
def inner():
print("x=%s" % x)
print("inner func excuted")
print("outer func excuted")
return inner # 返回内部函数名
outer()()

输出

outer func excuted
x=
inner func excuted
def outer():
x =
def inner():
print("x=%s" %x)
print("inner func excuted")
inner()
print("outer func excuted") outer()

输出

x=
inner func excuted
outer func excuted

code

def outer():
x =
y =
def inner():
print("x= %s" %x)
print("y= %s" %y) print(inner.__closure__)
return inner outer()

输出

(<cell at 0x102d6ea98: int object at 0x1009e0c80>, <cell at 0x102d6ebe8: int object at 0x1009e0ca0>)

类装饰器

class Foo(object):
def __init__(self, func):
self._func = func
def __call__(self):
print('class decorator runing')
self._func()
print('class decorator ending') @Foo
def bar():
print('bar') bar()

output

class decorator runing
bar
class decorator ending

类装饰器

class Foo(object):
def __init__(self):
pass
def __call__(self, func):
def _call(*args, **kw):
print('class decorator runing')
return func(*args, **kw)
return _call class Bar(object):
@Foo()
def bar(self, test, ids): # bar = Foo()(bar)
print('bar') Bar().bar('aa', 'ids')

output

class decorator runing
bar

装饰器的嵌套

import time
import random
def timmer(func):
def wrapper():
start_time = time.time()
func()
stop_time =time.time()
print('run time is %s' %(stop_time - start_time))
return wrapper def auth(func):
def deco():
name = input('name: ')
password = input('password: ')
if name == 'egon' and password == '':
print('login successful')
func() # wrapper()
else:
print('login err')
print("hahha")
return deco @auth # index = auth(timmer(index))
@timmer # index = timmer(index)
def index():
time.sleep()
print('welecome to index page')
index()

输出

name: egon
password:
login successful
welecome to index page
run time is 3.005250930786133
hahha

有参装饰器

import time
def outer(func): # 将index的地址传递给func
def inner(*args, **kwargs):
start_time = time.time()
func(*args, **kwargs) # fun = index 即func保存了外部index函数的地址
end_time = time.time()
print("运行时间为%s"%(end_time - start_time))
return inner # 返回inner的地址 @outer
def dd(a):
print("haha -> ",a) dd("xiaoming")

输出

haha ->  xiaoming
运行时间为5.626678466796875e-

无参数装饰器

import time, random

def outer(func):  # 将index的地址传递给func
def inner():
start_time = time.time()
func() # fun = index 即func保存了外部index函数的地址
end_time = time.time()
print("运行时间为%s"%(end_time - start_time))
return inner # 返回inner的地址 def index():
time.sleep(random.randrange(, ))
print("welcome to index page") @outer
def indexone():
time.sleep(random.randrange(, ))
print("welcome to index page") index = outer(index) # 这里返回的是inner的地址,并重新赋值给index
index() print("\n") indexone()

输出

welcome to index page
运行时间为4. welcome to index page
运行时间为1.

有参数装饰器

import time, random

def outer(func):  # 将index的地址传递给func
def inner(a):
start_time = time.time()
func(a) # fun = index 即func保存了外部index函数的地址
end_time = time.time()
print("运行时间为%s"%(end_time - start_time))
return inner # 返回inner的地址 def index(b):
time.sleep(random.randrange(, ))
print("welcome to index page",b) @outer
def indexone(a):
time.sleep(random.randrange(, ))
print("welcome to index page",a) index = outer(index) # 这里返回的是inner的地址,并重新赋值给index
index("bb") print("\n") indexone("aa")

输出

welcome to index page bb
运行时间为3. welcome to index page aa
运行时间为4.

被装饰的函数有返回值

import time
import random
def timmer(func):
def wrapper(*args,**kwargs):
print("kk")
print(*args)
start_time = time.time()
res=func(*args,**kwargs) #res来接收home函数的返回值
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return res
return wrapper @timmer
def home(name):
time.sleep(random.randrange(,))
print('welecome to %s HOME page' %name)
return print(home("haha"))

输出

kk
haha
welecome to haha HOME page
run time is 2.001023054122925

参考:

https://www.cnblogs.com/huchong/p/7725564.html#_label2

python 装饰器demo的更多相关文章

  1. python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...

  2. Python装饰器使用技巧

    装饰器 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多初次接触这个知识的人来讲,这个功能有点绕,自学时直接绕过去了,然后面试 ...

  3. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  4. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  5. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  6. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  7. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  8. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  9. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

随机推荐

  1. 敏感词检测、屏蔽设计(iOS & Android)

    敏感词检测 服务器端最常使用的算法是DFA算法.如果服务器端使用java实现常规的DFA算法,假若... 源码:https://github.com/qiyer/DFA_Cplusplus

  2. LinuxKernel优秀博客

    1.vanbreaker的专栏 2.LinuxKernel Exploration 3.DroidPhone的专栏 4.Linux内核研究以及学习文档和ARM学习以及研究的开放文档   [力荐] 5. ...

  3. 删除Ubuntu的UEFI启动项

    bcdedit 删除 千万不要手贱用diskpart之类的命令直接删除文件夹,大写的没,有,用! 感谢这个视频的up主,youtube看不到请翻墙.https://www.youtube.com/wa ...

  4. 学习python的日常

    今天是开始正式接触python语言的第一天,然后来自前辈的知道开始了在学习过程当中用博客来记录自己的学习历程,以供自己更快地掌握这门编程语言. 大概的总结一下的话,还是按照我的编程的习惯,要学写代码, ...

  5. WampServer详解

    php能做什么,它是运行在服务器端的,web网站大部分数据都是存储在服务器上的,PHP就是用来处理这些存储在服务器的数据.跨平台,服务器可以是多种平台上的服务器,脚本语言,免费. wampserver ...

  6. Burp Suite Extension tools

    1.Setting up the envrionment for burp Extensions   before we can write extensions we need to ensure ...

  7. linux系统多网卡热备实现高并发负载均衡

    #nmcli实现bonding #先停止NetworkManagerservice NetworkManager stop chkconfig NetworkManager off   //开机自启动 ...

  8. 【HICP Gauss】数据库 升级迁移维护-2

    DM-Data Manager 集群管理web工具 数据库升级 1.检查版本 依次升级.升级前全备数据 2.磁盘空间不小于表预留空间 3. 确保数据库对包有一定权限 4.升级后正常启停 python ...

  9. win下如何生成 github ssh公钥 GIT

    1. 安装git,可以去官网下最新的,但由于局域网问题,我们百度git即可,一般版本也比较新: 2. 一路默认下一步,安装成功后,从程序目录打开 "Git Bash": 3. 输入 ...

  10. 2013.5.2 - KDD第十四天

    今天早上来了之后就处理语料,然后发现处理好后的gbk编码的语料在HPC上没法训,而utf8在上面训练可以.后来就让它在上面训着,学长还没来. 学长回来之后问他怎么回事,他说不应该,然后我们看了一下第一 ...