前言
初学python时,第一次见到“@”符号,感觉很眼熟,如果是学习过java或者接触过AOP(面向切面编程),对于这个符号应该是比较熟悉的。实际上,python中的@也是AOP思想的一种实现。
python的@,官方语言叫做“decorators”,即装饰器。这是python的一大特性,对于初学者来说,很难透彻的理解decorators。本文以多个python例子为引,层层深入,帮助读者来透彻的理解decorators。
从函数开始
decorators和函数是密不可分的,因此必须对python的函数有所了解,之前我写过一篇函数基础的博客,链接如下:http://yunjianfei.iteye.com/blog/2186064
通过该博客,主要要了解的是:
1. 函数的基本概念:函数名、实参、形参、函数体、函数返回值
2. 作用域、生存周期的概念
嵌套函数与闭包
要理解decorator,嵌套函数与闭包也是需要了解的知识,这里我单独写了一个博客,链接如下:
http://yunjianfei.iteye.com/blog/2186092
通过该博客,主要要了解的是:
1. 函数是对象,所以函数可以在另一个函数中定义(嵌套函数)
2. 函数也可以赋给另一个变量 (类似C语言的函数指针)
3. 函数可以作为参数,也可以作为返回值(不执行该函数,只是返回)
4. 闭包是内部函数可以使用外部函数变量的机制
装饰器(Decorators)
装饰器其实就是调用时,把一个函数作为参数,把此函数封装后,返回一个替代函数。
读起来有点抽象,换句话说:装饰器其实就是在不修改原函数的基础上,在执行原函数的前后执行别的代码
我们看一个简单的例子,下面是手动实现的一个装饰器。
#!/usr/bin/env python def outer(some_func): def inner(): print "before some_func" ret = some_func() # 1 return ret + 1 return inner def foo(): return 1 decorated = outer(foo) # 2 print decorated() print "decorated 's __name__ : " + decorated.__name__
输出结果:
2
decorated 's __name__ : inner
这个例子有以下要点:
1. outer函数有一个名为some_func的参数,在outer函数里定义了一个嵌套函数inner,outer将inner函数作为 返回值返回(注意:并没有去调用inner,只是将inner作为变量返回)
2. inner函数打印了一行字符串,然后调用了some_func,并且在#1处获取了some_func的返回值
3. outer每次调用时,参数some_func的值可能会不同,但是我们都会在inner中去调用这个函数。
4. inner在结束时,其返回值是some_func()+1
5. 在#2处,调用了outer函数(foo函数作为参数),并将返回的inner函数作为赋值给decorated
6.最后调用decorated()函数,执行inner,打印一行,并在inner中调用foo函数,最后返回2
上面这个例子可以用一句话概括:变量decorated是将foo函数装饰后(封装后)的版本,或者说,foo函数前后附加其他的一些代码。
decorated = outer(foo)
上面的这一行代码其实就是装饰器的本质。下面的例子用我们一般见到的“@”,也就是装饰器的一般用法来写,如下:
#!/usr/bin/env python def outer(some_func): def inner(): print "before some_func" ret = some_func() # 1 return ret + 1 return inner @outer def foo(): return 1 print foo() print "foo's __name__ : " + foo.__name__ #2
执行结果为:
2
foo's __name__ : inner
上面的两套代码是等价的。
@outer这一行,实际上执行的就是:
foo = outer(foo)
注意:#2处打印了foo的__name__,打印结果为:inner。这再次印证了我们开头处的一句话:
函数装饰器就是把一个函数作为参数,把此函数封装后,返回一个替代函数。
对应上面的代码,就是:
outer装饰器,把foo函数作为参数,把foo封装成inner后,返回inner。
一定要用嵌套函数吗
第一次看到装饰器的时候,估计有很多人都疑惑过,为啥就是嵌套函数呢?好吧,其实也可以不用嵌套函数的,看下面的例子:
#!/usr/bin/env python some_func = None #1 def outer(func): global some_func some_func = func #2 return inner def inner(): print "before some_func" ret = some_func() # 3 return ret + 1 @outer def foo(): return 1 print foo() print "foo's __name__ : " + foo.__name__
这个例子比上面嵌套函数的装饰器版本复杂了不少,但是效果是等同的。这样一比较,从各个角度来看,嵌套函数的写法显然要简洁很多。
收尾
上面介绍装饰器的时候,其实只是介绍了装饰器里最基本的部分,函数装饰器相关,鉴于篇幅,暂时先不在这里写了。
相关推荐
python方法 python_装饰器Decorators
Project为现代工具(如 , 实现了装饰器 安装 npm install @decorators/di --save npm install @decorators/express --save npm install @decorators/socket --save 使用例 这是Express框架用法的示例。 它使用...
exports = { addons : [ '@socheatsok78/storybook-addon-vuetify' ]} 将vueitfy装饰器添加到.storybook/preview.js import { withVuetify } from '@socheatsok78/storybook-addon-vuetify/dist/decorators'ex
CoreFunc装饰器现代JavaScript的装饰器。 请注意:这是“进行中”程序包。...例子方法装饰器试图 import { attempt } from "@corefunc/decorators" ;class Kitty { @ attempt ( ( error : Error , args :
装饰器版本。 隐式注入intl服务。 创建一个取决于当前语言环境和您作为第二个参数传递的键的计算属性。 import Component from '@ember/component' ; import { t } from '@ember-intl/decorators' ; class ...
lodash 装饰器 随着,现在似乎是实现lodash和underscore提供的一些最有用的一些的好时机。 由于目前还没有环境或转译器完全支持生成器,因此此 repo 中的代码是假设性的。 (后续更新)。 我已经制作了最有用的包装...
python库。 资源全名:comapsmarthome-lambda-decorators-1.0.1.tar.gz
python库。 资源全名:aws-lambda-decorators-0.51.tar.gz
资源分类:Python库 所属语言:Python 资源全名:aws_lambda_decorators-0.32-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
gem 'little_decorator'用法创建您的装饰器在app/decorators器中添加装饰app/decorators : # app/decorators/user_decorator.rbclass UserDecorator < LittleDecorator def full_name " #{ first_name } #{ ...
Axios装饰器 它是使用Axios和JavaScript装饰器的HTTP客户端库。 它受到流行的Android库启发。 依存关系 主要依赖项是Babel,它使用装饰器和类使JavaScript开发人员的生活更轻松。 因此,有两个依赖项,例如和 。 ...
python库,解压后可用。 资源全名:aws_lambda_decorators-0.45-py3-none-any.whl
python库,解压后可用。 资源全名:kafka_client_decorators-0.9.2-py3-none-any.whl
各类速查表汇总-Python Decorators Decorators 基础命令速查
Polyfills Ember的内置装饰器 兼容性 Ember.js v2.18或更高版本 Ember CLI v2.13或更高版本 在Ember 3.10+中不需要此附加组件 安装 ember install ember-decorators-polyfill 用法 Polyfills Ember的内置装饰器API...
JS 装饰器一个将 python 风格的装饰器引入 javascript 的小型编译器。用 import Compiler from '../lib/compiler' ;var compiler = new Compiler ( ) ;var result = compiler . compile ( source ) ;例子 // ...
使用以下格式之一指定带有@Decorate注释的装饰器: 类名::方法名 类名(必须实现__invoke) 函数名 装饰器将原始方法和上下文作为参数,并且必须返回一个函数,该函数采用与原始方法相同的参数。 可以根据需要...
使用装饰器将JSON之类的数据转换为类并返回。 使用简单易用的修饰符为数据类添加注释,然后将标准JSON解析为实际的类实例。 为了获得更多的类型安全性和更少的语法,建议与一起使用, 是用于装饰器元数据的ES7 ...
资源分类:Python库 所属语言:Python 资源全名:lambda-decorators-0.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059