如何理解python装饰器
@(Python学习-随手记)[Decorator, 帮助]
装饰器简介
-
装饰器decorator是一种高级python语法,可以对函数、方法、类进行加工。
-
装饰器常用场景:插入日志、性能测试、事务处理、web权限校验、cache等。
-
装饰器的作用:可以将函数装饰为完全不同的行为,概括的讲:装饰器的作用就是为已经存在的对象添加额外的功能。
-
案例:如果记录日志,需要对某些函数进行记录,笨的方式就是对每个函数加入代码,如果代码发生变化,修改的代价比较多;还有一种就是定义一个专门日志记录的装饰器,对需要的函数进行装饰即可。
-
装饰器decorator:重点理解装饰。
-
python的Decorator在使用上使用
@XXXX
注解为方法装饰一些东西。
装饰器的原理
- 在python中,装饰器方便的原因:
函数可以被扔来扔去
。
python的函数就是对象
- 在python中,函数也是对象function are objects。
#!/use/bin/python
# -*- coding: utf-8 -*-
"""
@Author : bdeng
@software:pythonProject
@Create : 2021/11/29 上午11:20
@Package: Demo_Decorator.py
@Description:
"""
# 定义函数
def shout(word="yes"):
# 字符串首字母大写
return word.capitalize()+"!"
# 调用函数
print shout()
print id(shout)
print "函数名赋值给scream"
# 函数作为一个对象,可以将其复制给其他变量
scream = shout
print scream()
print id(scream)
# 可以将原有的函数名删除,不影响scream访问
print "删除原有函数名"
del shout
try:
print shout()
except Exception as e:
# 打印name 'shout' is not defined
print e
# 正常打印:Yes!
print scream()
- python函数还有一个特别有意思的特性:可以在另外一个函数体内定义。
#!/use/bin/python
# -*- coding: utf-8 -*-
"""
@Author : bdeng
@software:pythonProject
@Create : 2021/11/29 下午1:38
@Package: Demo_Decorator_2.py.py
@Description:
"""
# 定义外部函数
def talk():
# 定义内部函数
def whisper(work="yes"):
return work.lower()+"..."
# 直接调用内部函数
print whisper()
"""
1、调用外部函数:正常输出-yes...
2、每当调用talk函数时,内部都会定义一次whisper,然后被调用执行
3、内部函数只在外部函数体内有效
"""
talk()
try:
# 内部函数作用于只在外部函数内部,编译报错
whisper()
except Exception as e:
# name 'whisper' is not defined
print e
函数引用 Functions references
- 由上得知:
- python函数也是对象,可以被赋值给变量
- python函数也是对象,可以被定义在另外一个函数体内
- 那么就意味着:一个函数可以返回另一个函数
#!/use/bin/python
# -*- coding: utf-8 -*-
"""
@Author : bdeng
@software:pythonProject
@Create : 2021/11/29 下午1:55
@Package: Demo_Decorator_3.py
@Description:
"""
# 定义外部函数
def get_talk(type="shout"):
# 定义内部函数
def shout(word="yes"):
return word.capitalize()+"!"
def whisper(word="yes"):
return word.lower()+"..."
# 根据type判断返回一个内部函数
if type == "shout":
# 返回函数对象,不是调用函数
return shout
else:
return whisper
# talk指向内部函数shout
talk = get_talk()
# 打印内部函数shout返回值:Yes!
print talk()
# 打印发现talk本质上是一个函数对象shout: <function shout at 0x7fe0cc0ddcd0>
print talk
# 根据type不同执行不同的内部函数,正常打印:yes...
print get_talk("whisper")()
- 同理:既然一个函数可以返回另外一个函数对象,那么也可以像参数一样传递
#!/use/bin/python
# -*- coding: utf-8 -*-
"""
@Author : bdeng
@software:pythonProject
@Create : 2021/11/29 下午2:24
@Package: Demo_Decorator_4.py
@Description:
"""
# 定义函数
def shout(word="yes"):
return word.capitalize()+"!"
# 函数对象赋值
scream = shout
def do_something_before(func):
# 我之前做了一些事情然后调用你给我的函数
print "I do something before then i call the function you gave me"
# Yes!
print func()
do_something_before(scream)
# outputs:
# I do something before then I call the function you gave me
# Yes!
装饰器实战
- 装饰器其实就是包装材料,他可以让你在执行被装饰的函数之前或之后执行其他代码,而且不需要修改函数本身。
手动制作装饰器
- 一个装饰器:就是一个需要另外一个函数作为参数的函数,即函数参数式
#!/use/bin/python
# -*- coding: utf-8 -*-
"""
@Author : bdeng
@software:pythonProject
@Create : 2021/11/29 下午2:50
@Package: Demo_Decorator_5.py
@Description:
"""
# 一个装饰器:就是一个需要另外一个函数作为参数的函数
def <