Python 装饰器 decorator (函数定义前的@XXX) 极简介绍

我们时常看到这样的python写法——Python函数定义前面加了一坨@XXX。

@my_decorator
def my_func():
    print "I am a stand-alone function"

它的功能是:在不改动my_func()的前提下,实现以my_func为核心的功能扩展。

例如,在某种扩展方式下,my_func()的执行结果是:func()的输出上下各增加一行:

>> my_func()
# output
Before the function runs
I am a stand-alone function
After the function runs

上述某种扩展是在哪里定义的呢——在函数my_decorator里,其定义如下:

def my_decorator(func):
    def wrapper():
        print "Before the function runs"
        func()
        print "After the function runs"
    return wrapper

## 写法1
@my_decorator
def my_func():
    print "I am a stand-alone function"

## 写法1 调用my_func()即可

>> my_func
Before the function runs
I am a stand-alone function
After the function runs

上述写法即@XXX,代码中的写法1。当然,大家更熟悉的写法2是这样的,没有那一坨@XXX:

def my_decorator(func):
    def wrapper():
        print "Before the function runs"
        func()
        print "After the function runs"
    return wrapper

## 写法2
def my_func():
    print "I am a stand-alone function"

new_my_func = my_decorator(my_func)

## 写法2 调用new_my_func()即可

>> new_my_func
Before the function runs
I am a stand-alone function
After the function runs

基于这样的写法,我们实现了核心功能func()与外围装饰的分离。

Python用一个简单的@,实现了设计模式中的装饰器模式decorator。

更一般例子,下述代码在没有改变func的情况下,调用func()时执行了deco的内容:

def deco(fn):
    print "I am %s!" % fn.__name__

@deco
def func():
    pass

# output
>> func()
I am func!

# 没有执行func 函数 但是 deco 被执行了

一种更有趣的用法:汉堡包还是披萨?——嵌套decorator,举例如下

def bread(func):
    def wrapper():
        print "</''''''\>"
        func()
        print "<\______/>"
    return wrapper

def ingredients(func):
    def wrapper():
        print "#tomatoes#"
        func()
        print "~salad~"
    return wrapper

## 写法1
@bread
@ingredients
def sandwich(food="--ham--"):
    print food

## 写法1调用sandwich()
>> sandwich()

#### outputs
# </''''''\>
#  #tomatoes#
#  --ham--
#  ~salad~
# <\______/>

## 写法2

def sandwich(food="--ham--"):
    print food

## 写法2调用my_sandwich
>> my_sandwich = bread(ingredients(sandwich))
>> my_sandwich()

#### outputs
# </''''''\>
#  #tomatoes#
#  --ham--
#  ~salad~
# <\______/>

面包Bread在外层,蔬菜和沙拉Ingredients在中层,肉Ham在内层,我们得到了汉堡。

而把ingredients和bread反过来,蔬菜和沙拉Ingredients在外层,面包Bread在中层,肉在内层,我们得到了披萨:

@ingredients
@bread
def sandwich(food="--ham--"):
    print food

# outputs:
    
# #tomatoes#
# </' ' ' ' ' '\>
#   --ham--
# <\______/>
# ~salad~

所有例子来源于:Python 装饰器使用指南 - SegmentFault 思否

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值