博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
所不为人知的Python装饰器
阅读量:7027 次
发布时间:2019-06-28

本文共 2340 字,大约阅读时间需要 7 分钟。

装饰器可以说是Python中非常重要的特性之一。有些人要么从没使用过装饰器,要么就是对装饰器的使用一知半解。也有些人觉得装饰器很简单:"装饰器不就是那些把函数作为参数并输出一个函数的函数"。这里介绍一些装饰器“所不为人知”的一些地方。

先回顾一下函数。函数在python中是一等公民,也就是说,函数也是对象,它可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值、也有属性。

例如:

1.1.输出函数f的所有属性

def f():    print('something')print(dir(f))
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

1.2.赋值给一个变量g

g = fg()
something

1.3.作为参数传递给其他函数

def func_name(function):    return function.__name__func_name(f)
f

1.4.作为元素添加到集合对象list中

function_collection = [f, g]for function in function_collection:    function()
somethingsomething

装饰器常常被描述成“装饰器就是那些把函数作为参数并输出一个函数的函数”,严格地讲,这并不是很准确。其实,他还有如下一些细节:

  • 在函数定义的时候就执行了一次装饰器的装饰过程
  • @d装饰一个函数定义x,等价于,先定义函数x,然后执行x=d(x)
  • @d和@e装饰一个函数定义x,等价于,先定义函数x,然后执行x=e(d(x))

举几个例子会更加让人理解。

def print_when_called(function):    def new_function(*args, **kwargs):        print("{} was called".format(function.__name__))        return function(*args, **kwargs)    return new_functiondef one():    return 1one = print_when_called(one)@print_when_calleddef two():    return 2[one(), two(), one(), two()]
one was calledtwo was calledone was calledtwo was called[1, 2, 1, 2]

你可能会注意到,上面的输出是在执行[one(), two(), one(), two()]后才打印出来,实际上,在one()或two()执行前,print_when_called就已经返回了负责打印的new_function。下面的例子会更容易理解些:

def print_when_applied(function):    print("print_when_applied was applied to {}".format(function.__name__))    return function@print_when_applieddef never_called():    print("never_called")
print_when_applied was applied to never_called

显而易见,never_called”没有被执行,但是“print_when_applied was applied to never_called”已经打印出来了。

下面再说一下装饰器执行的顺序。

@print_when_applied@print_when_calleddef this_name_will_be_printed_when_called_but_not_at_definition_time():    pass this_name_will_be_printed_when_called_but_not_at_definition_time()
print_when_applied was applied to new_functionthis_name_will_be_printed_when_called_but_not_at_definition_time was calle

 

转载于:https://www.cnblogs.com/fingerling/p/8252110.html

你可能感兴趣的文章
用java swing做连连看_java基于swing实现的连连看代码
查看>>
java关键字定义字符变量_Java 关键字和标识符
查看>>
java并发编程核心方法与框架_Java并发编程核心方法与框架-CompletionService的使用...
查看>>
java开源api网关_常用的几个开源 API网关管理系统
查看>>
java 数据结构 快速入门_Java 数据结构
查看>>
mysql 事务 隔离级别_MySQL中四种事务隔离级别详解
查看>>
leetcode 459 java_【leetcode刷题】[简单]459. 重复的子字符串(repeated substring pattern)-java...
查看>>
oracle12 se1和se2,小屏党的最终执念,12Mini和SE2,到底谁更值得入手?
查看>>
include top.php,Php 安全错误 Top 7
查看>>
oracle itl槽,事务槽(ITL)
查看>>
Redis中使用Lua脚本的开发思路
查看>>
重新审视美国爱因斯坦计划(2016)
查看>>
微信公众平台小程序开放公测
查看>>
【VMC实验室】在QCloud上创建您的SQL Cluster(3)
查看>>
发一个经典的Flask-SQLAlchemy使用场景
查看>>
企业shell常见面试题及企业实战案例深入浅出讲解
查看>>
VMware Workstation 12-虚拟机-批量创建-快照-批量创建恢复
查看>>
Oracle 变量绑定与变量窥视合集系列一
查看>>
只要3分钟,Python生成器原理详解
查看>>
51CTO梦想的摇篮【我与51CTO一“七”成长】
查看>>