想要弄明白装饰器是什么东西,首先我们需要了解一下什么是闭包,因为装饰器是闭包的一种应用。

闭包

闭包的定义:

​通俗的来说闭包就是在一个函数内部定义另外一个函数,这个函数又引用了外部函数的变量,并且外函数的返回值是内函数的引用,下面是一个最简单的闭包示例:

def outer():

a = 10

def inner():

print(a)

return inner

demo = outer()

demo()

那么再回到装饰器上面,我们都知道在python中任何东西都是对象,一个函数也好一个字符串也好都是对象,在传递过程中都是传递其内容的引用,当传递的是函数的时候只需在变量名后边加上()即可调用这个函数。

好了基础知识了解了,那么下面来看一个简单的装饰器应用:

装饰器

def auth(func):

print('before run')

def wrapper():

func()

return wrapper

@auth

def response():

print('this is a test function')

response()

###### result ######

# before run

# this is a test function

乍一看是不是和闭包一样,只不过把变量替换成函数名了

参数的传递

上面的示例中被装饰函数是没有传递参数的,倘若被装饰函数需要传递参数的时候那么就需要稍微做一下调整。

def auth(func):

print('before run')

def wrapper(*args, **kwargs):

func(*args, **kwargs)

return wrapper

@auth

def response(*args, **kwargs):

print('this is a test function')

print(args)

response(1,2)

###### result ######

# before run

# this is a test function

# (1, 2)

装饰器的高级用法

有时候实际使用装饰器的时候可能并不会像上面的那样简单,例如我们可能需要给装饰器本身传递参数,来让装饰器更为灵活。先尝试不改代码看看运行的结果

@auth(1,2)

def response(*args, **kwargs):

print('this is a test function')

print(args)

response(1, 2)

###### result ######

# error:

# TypeError: auth() takes 1 positional argument but 2 were given

auth只有一个参数,但是传递了两个参数,这是为什么呢?我们需要先看看@auth这行代码是什么意思,@auth其实是response=auth(response)的简写,你看这样的写法就只接收一个参数,那么我们不使用这种简写方式可以吗?

def auth(func, *args):

print('before run')

print(args)

def wrapper(*args, **kwargs):

func(*args, **kwargs)

return wrapper

def response(*args, **kwargs):

print('this is a test function')

print(args)

response = auth(response, 1)

response(1, 2)

###### result ######

# before run

# (1,)

# this is a test function

# (1, 2)

你看还真是实现了这个功能,只不过没办法使用简写来装饰函数了。那有没有更好的解决方法呢,我们再回到装饰器的原理上(一个闭包)那如果我们在闭包函数外面再套一层函数是不是就可以解决了呢。尝试一下

def outer(*args, **kwargs):

print('before run')

print(args)

def inner(func):

def wrapper(*args, **kwargs):

func(*args, **kwargs)

return wrapper

return inner

@outer(1, 2)

def response(*args, **kwargs):

print('this is a test function')

print(args)

response(3, 4)

###### result ######

# before run

# (1,)

# this is a test function

# (1, 2)

实现了和上一个一样的功能,此时的@outer(1,2)还原成本来样子就是 response = outer(1,2)(response),我们打上断点看看装饰器是如何运行的

多个装饰器同时使用

先上代码看结果

def decorator1(func):

print('Decorator1')

def wrapper(*args,**kwargs):

print('----1----')

func(*args, **kwargs)

return wrapper

def decorator2(func):

print('Decorator2')

def wrapper(*args,**kwargs):

print('----2----')

func(*args, **kwargs)

return wrapper

@decorator1

@decorator2

def test(*args):

print(args)

test(1,2)

###### result ######

# Decorator2

# Decorator1

# ----1----

# ----2----

# (1, 2)

执行顺序并不是先执行完装饰器1然后在执行装饰器2,而是交替运行的,我们分析一下具体执行过程一探究竟。就装饰顺序来说还是按照decorator1、decorator2来对原函数装饰的,那么装饰的结果是什么呢,这里需要了解一下@符号的作用,在python中@会将紧跟着的函数名作为参数传给装饰函数,经过两个装饰器作用之后 test变成了 :test = decorator1(decorator2(test))

此时在调用test的时候,就会从里往外执行,

即先执行decorator2(test),会先打印出Decorator2

返回decorator2中的内函数给decorator1,然后打印Decorator1

返回decorator1内函数给test

在调用test函数的时候就会先执行decorator1的内函数,打印出了----1----

然后运行decorator2的内函数,打印出----2----

最后才会运行test原函数

总结来说,在装饰过程中越靠近被装饰函数越先执行,内函数恰恰相反**

保留原函数的信息

回到之前一个最简单的装饰器上,我们看看直接输出被装饰的函数信息是什么?

def auth(func):

def wrapper():

func()

return wrapper

@auth

def response():

pass

print(response.__name__)

###### result ######

# wrapper

输出的是装饰器的内函数,原因就不说了,和之前的一样@的作用,难么我们该怎么让打印函数信息能够显示的是被装饰函数本身呢?这里就要用到functools的wraps方法,用法很简单:

from functools import wraps

def auth(func):

@wraps(func)

def wrapper():

func()

return wrapper

@auth

def response():

pass

print(response.__name__)

###### result ######

# response

总结

装饰器到此差不多都说完了,其作用就不展开说了,经过这么一连串的分析自己也对装饰器的原理有了更深的了解,算是没白浪费时间。

python装饰器是什么意思_对Python装饰器的理解相关推荐

  1. python装饰器使用多吗_对于Python装饰器使用的一些建议

    关于python装饰器的问题 这里 函数 man和 woman分别作为func1的参数了嘛?如果是的话为什么会这装饰器函数参数要传函数,而不是字符串. 装饰器函数特点: 1,参数为函数对象 2,使用内 ...

  2. 装饰器python3菜鸟教程_认识Python装饰器

    Python中的装饰器用来给Python中的函数添加一些辅助功能.比如我们可以把[输出日志]这个辅助功能写到一个装饰器里.只要我们在某个函数A之前添加了这个[输出日志]的装饰器,那么执行函数A的时候, ...

  3. python pygame模块怎么写游戏_使用 Python 和 Pygame 模块构建一个游戏框架

    这系列的第一篇通过创建一个简单的骰子游戏来探究 Python.现在是来从零制作你自己的游戏的时间. 在我的这系列的第一篇文章 中, 我已经讲解如何使用 Python 创建一个简单的.基于文本的骰子游戏 ...

  4. python解释器用什么写的_用 Python 从零开始写一个简单的解释器(3)

    到目前为止,我们已经为解释器写了一个词法分析器和 一个解析器组合子库.在这里,我们会创建抽象语法树(AST)的数据结构,使用组合子库写一个解析器,组合子库可以实现将词法分析器返回的标记列表转换为一个抽 ...

  5. python发行版是什么意思_致 Python 初学者

    当下是一个喧嚣.浮躁的时代.我们总是被生活中大量涌现的热点所吸引,几乎没有深度阅读和思考的时间和机会.我始终认为,学习是需要沉下心来慢慢钻研的,是长期的:同时,学习不应该被赋予太多的功利色彩.一个Py ...

  6. python的flask框架显示柱状图_使用Python的Flask框架,结合Highchart,动态渲染图表...

    服务端动态渲染图表 参考文章链接:https://www.highcharts.com.cn/docs/dynamic-produce-html-page 参考文章是使用php写的,我这边改用pyth ...

  7. python语言下划线怎么打_初学Python语言者必须理解的下划线

    下划线(_)在Python语言中有特殊作用. 在大多数编程语言中,下划线是命名变量或者函数名称时的连字符,但是,在Python语言中,不仅如此.如果你是一名Python程序员,对于诸如 _ in ra ...

  8. python适合找哪方面工作_学习python后能做哪方面的工作

    Python作为一种功能强大的编程语言,因其简单易学而受到很多开发者的青睐.那么,Python 的应用领域有哪些呢? 概括起来,Python的应用领域主要有如下几个,这也是学完python将要从事的相 ...

  9. python哪个关键字可以导入模块_关于python导入模块import与常见的模块详解

    0.什么是python模块?干什么的用的? Java中如果使用abs()函数,则需要需要导入Math包,同样python也是封装的,因为python提供的函数太多,所以根据函数的功能将其封装在不同的m ...

最新文章

  1. java用opencv实现滤镜_opencv滤镜-二值化实现黑白滤镜
  2. 安装 Ruby 和 Rails 开发环境
  3. onMeasure模式
  4. 并归排序(看别人的看不懂,自己写了一个),排序思想是一样的
  5. C语言指针,这可能是史上最干最全的讲解啦(附代码)!!!
  6. 3dsmax怎么添加uv坐标_YND科研绘图3Dsmax基础操作
  7. 设计灵感|浓浓人文感!中文活动海报设计学习案例
  8. Oracle故障:Breaking the connection before proto/dty negotiation, error raised 3136
  9. 计算机培训中学语文研修计划,初中语文个人研修计划书
  10. Java运行报错问题——Picked up JAVA_TOOL_OPTIONS: -agentlib:jvmhook
  11. CMU 15-213 Introduction to Computer Systems学习笔记(10) The Memory Hierarchy
  12. 如何把SWF转为PDF文件
  13. google地图距离算法_java – 使用谷歌地图计算实际行进距离
  14. excel批量删除单元格中的部分内容
  15. Debian Etch 源配置
  16. hadoop 不能加载native-hadoop library问题
  17. 解析华为OSPF协议
  18. JAVA练习 家庭记账本
  19. 荣耀路由器搭建php,荣耀路由器怎么设置? – 192路由网
  20. 截至2012年5月23日19点58分支持CUDA的NVIDIA的GPU列表(Geforce)

热门文章

  1. erlang的运算符
  2. 使用Redis进行搜索
  3. 一个项目部署多个节点会导致锁失效么_不为人知的分布式锁实现,全都在这里了
  4. windows10 ubuntu16.04 双硬盘安装双系统安装
  5. 计算机网络考研辅导谁的好,计算机网络考研辅导哪个好
  6. html5 tooltips,纯js轻量级tooltips工具提示插件
  7. python68个内置函数_直接在python中检索68个内置函数?
  8. python保存后不运行_Python后台执行不启用缓存
  9. 扩展中断控制器8259实验_PCIe的中断机制
  10. 有计算机考试励志的文案,关于考试的句子励志