在面试的时候,被问到装饰器,在用的最多的时候就@classmethod ,@staticmethod,开口胡乱回答想这和C#的static public 关键字是不是一样的,等面试回来一看,哇,原来是这样,真佩服我当时厚着脸皮回答的那些问题...

OK,先来张图看看装饰器内容:

OK,我们留下一个印象,然后我们看实际的场景来操作.

我们先看一个方法:

__author__ = 'bruce'

def do_sth():
print 'some thing has been done' if __name__ == '__main__':
do_sth()

  

假定一个方法,我们现在提出一个需求,将每个方法追加一个写日志的功能,这样方便我们统计。

第一次更改:硬代码

__author__ = 'bruce'

def do_sth():
print 'the function is begin'
print 'some thing has been done'
print 'the function is end' if __name__ == '__main__':
do_sth()

看样子是符合需求,但是这里一个问题,现在只是针对特定的do_sth()方法了,那如果我们还有do_first_sth(),do_second_sth()......等更多的方法,难道我们每一个都是都去copy然后在去粘贴这些内容吗?

第二次更改:灵活变动

__author__ = 'bruce'

def do_sth():
print 'some thing has been done' def log_sth(func):
print 'the function is begin'
func()
print 'the function is end' if __name__ == '__main__':
log_sth(do_sth)

这样,方法被当作参数一样传递给log_sth,这样我们只需要调用log_sth就可以灵活的写日志了,在逻辑上当然没有问题了,假如do_sth()被N处调用,那我们是不是必须得把do_sth()在N处都要更改过来,那假如你的这个函数是给别人使用的,你这样修改直接导致别人无法使用了。

第三次更改:内置引用

__author__ = 'bruce'

def do_sth():
print 'some thing has been done' def log_sth(func):
def wrapper():
print 'the function is begin'
func()
print 'the function is end' return wrapper if __name__ == '__main__':
foo = log_sth(do_sth)
foo()

这样就内置的实现了一个函数调用另一个函数,我们可以很形象的手中有两张牌然后插入另外一张牌,很像一个横切面,这个就叫叫面向切面编程(AOP),每次调用dosth时,都从上到下顺序的执行了外层函数,从语义上来看do_sth这个方法被log_sth这个词语修饰了,这种行为在python就是装饰器,python有更优雅的方法实现这个操作

__author__ = 'bruce'

def log_sth(func):
def wrapper():
print 'the function is begin'
func()
print 'the function is end' return wrapper @log_sth
def do_sth():
print 'some thing has been done' if __name__ == '__main__':
do_sth()

@log_sth就像是形容词一样,放置在do_sth函数的上方

有人会说,你这只是针对于没有参数的函数,那如果有参数的函数应该怎么写呢?

第四次变更:针对有参数的函数的装饰器

__author__ = 'bruce'

def log_sth(func):
def wrapper(*args, **kwargs):
print 'the function is begin'
func(*args, **kwargs)
print 'the function is end' return wrapper @log_sth
def do_sth(sth=None):
if not sth:
sth = 'there is nothing'
print sth if __name__ == '__main__':
do_sth()

OK,通过上面一些简单的实例,我们了解到装饰器的一些实际应用,关于更多的例子请参考如下的列表:

Python的Decorator 杂谈
Python装饰器学习(九步入门)
理解Python中的装饰器
 

[python基础]关于装饰器的更多相关文章

  1. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  2. 十. Python基础(10)--装饰器

    十. Python基础(10)--装饰器 1 ● 装饰器 A decorator is a function that take a function as an argument and retur ...

  3. Day11 Python基础之装饰器(高级函数)(九)

    在python中,装饰器.生成器和迭代器是特别重要的高级函数   https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...

  4. 1.16 Python基础知识 - 装饰器初识

    Python中的装饰器就是函数,作用就是包装其他函数,为他们起到修饰作用.在不修改源代码的情况下,为这些函数额外添加一些功能,像日志记录,性能测试等.一个函数可以使用多个装饰器,产生的结果与装饰器的位 ...

  5. python基础-----函数/装饰器

    函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 函数的优点之一是,可以将代码块与主程 ...

  6. python基础之装饰器(实例)

    1.必备 #### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print ...

  7. 【Python基础】装饰器的解释和用法

    装饰器的用法比较简单,但是理解装饰器的原理还是比较复杂的,考虑到接下来的爬虫框架中很多用到装饰器的地方,我们先来讲解一下. 函数 我们定义了一个函数,没有什么具体操作,只是返回一个固定值 请注意一下缩 ...

  8. 学习PYTHON之路, DAY 5 - PYTHON 基础 5 (装饰器,字符格式化,递归,迭代器,生成器)

    ---恢复内容开始--- 一 装饰器 1 单层装饰器 def outer(func): def inner(): print('long') func() print('after') return ...

  9. Python基础之装饰器

    1.什么是装饰器? Python的装饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator搞混了,其实这是完全不同的两个东西.虽然 ...

随机推荐

  1. [转]phoneGap3.0安装步骤(以windows下的android环境为例):

    phoneGap3.0安装步骤(以windows下的android环境为例): 环境: WIN系统,JDK,Android,Eclipse,Ant,Git,PhoneGap3.x (Cordova) ...

  2. EntityFunctions.AsNonUnicode

    http://blog.csdn.net/zzx3q/article/details/7863797 使用工具VS2010 凡是调用FindAll的地方,如果传入参数是String类型的变量(数字类型 ...

  3. 【转】MongoDB安全配置

    [转自]http://drops.wooyun.org/%E8%BF%90%E7%BB%B4%E5%AE%89%E5%85%A8/2470 0x00 MongoDB权限介绍 1.MongoDB安装时不 ...

  4. PC远程调试移动设备

    我们在移动端进行前端开发时,会遇到一个让人头痛但不得不面对的问题——调试. 在 PC 机器上,我们有功能强大的 Chrome DevTools.Firebug,即便是老版本的 IE ,我们也可以安装微 ...

  5. FusionCharts简单教程(三)-----FusionCharts的基本属性

          通过前面两章的讲解我们可以制作出简单的图像,但是有时候我们需要对图像进行一个精确的规划,比如设置背景颜色.设置提示信息.设置间隔颜色等等,这时就需要我们对FusionCharts的细节有比 ...

  6. jQuery实现返回顶部

    由于项目需要,写了个返回顶部的小功能... /*返回顶部*/ function toTop() { $(".to_top").hide(); $(window).scroll(fu ...

  7. redis数据结构整理(一)

    摘要: 0.redis安装 1.redis的常用数据结构类型 1.1  String 1.2  List 1.3  Set 1.4  Sorted Set 1.5  Hash 2.redis是单进程单 ...

  8. atitit 业务 触发器原理. 与事件原理 docx

    atitit 业务 触发器原理. 与事件原理 docx 1.1. 呵呵,你需要需要一个业务 触发器..1 1.2. 触发器/事件/中断的原理1 1.3. Io 硬件中断的原理( 中断的低层有cpu轮询 ...

  9. 浅谈iOS版本号

    作者:Travis FIR.im 一直在尽量兼容不同使用习惯的版本号形式, 但是在使用中我们发现好多开发者对怎么更好的用版本号来标示应用很陌生. 这是篇基础文章, 简单介绍 iOS 的版本号. 名词解 ...

  10. angularjs的$filter使用

    angularjs的$filter使用 $filter服务可以在js中对数据进行过滤处理,ng有几个内建的filter,其中有一个叫filter的filter,可方便的实现属性的过滤. 详细的API参 ...