python中decorator的用法及原理(一)

本文详细介绍了Python中的装饰器概念,包括不带参数的装饰器、带参数的装饰器及其内部工作原理。此外还探讨了装饰器如何应用于类成员函数及多个装饰器的叠加使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0、 概念

什么叫装饰器,其实也可以叫做包装器。即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来。

python中的装饰器分为两类:函数装饰器和类装饰器。

这里我们先讨论函数装饰器。

1. 不带参数的decorator

(1) 基本用法:

def decorator1(func):
    def dec(*args):
        print 'pre action'
        result = func(*args)
        print 'post action'
        return result
    return dec

@decorator1
def test_f1(name):
    print name
    return None

test_f1('name1') #out: preaction/name1/post action
test_f1('name2') #out: preaction/name2/post action

(2) 这种现象的内部原理:

在python内部,当你做了这件事情:

@decorator1
def test_f1(name):

其实就是 test_f1 = decorator1(test_f1) #即test_f1作为参数传递给func。

此后的test_f1是装饰器中的dec函数对象了,而不是原来的函数的名称。当调用test_f1(‘name1’)的时候,其实调用的是dec(‘name1’)函数,而在dec函数内部,又调用了func,这样就造成了装饰器的效果。

这也解释了func是被装饰函数,*arg是被装饰函数的参数—这种现象了。


2. 带参数的decorator

(1) 基本用法:

def wap(name):
    def decorator1(func):
        def dec(*args):
            print name
            print 'pre action'
            result = func(*args)
            print 'post action'
            return result
        return dec
    return decorator1

@wap('f1')
def test_f1(name):
    print name
    return None

@wap('f2')
def test_f2(name):
    print name
    return None

test_f1('name1') #out: f1/pre action/name1/post action
test_f1('name2') #out: f2/pre action/name2/post action

带参数的decorator,作用是通过传递参数可以定制不同的装饰器。


(2) 内部原理

这里和上面 不带参数的decorator类似,

@wap('f1')
def test_f1(name):

内部逻辑为: test_f1 = wap(‘f1’)(test_f1)

这里wap(‘f1’)返回是decorator1函数对象,这样的话,wap(‘f1’)(test_f1)其实就是decorator1(test_f1),这样就和上面的一样了。只不过这里传递了一个参数’f1’进入decorator内部,使得我们可以操作这个参数。


3. 函数decorator也可以修饰类成员函数

class FOO:
    @decorator1
    def fun(self):
        print self.name

注意此时fun的self会被传递到decorator1中。此时把self看做普通的函数入参。


4. 函数decorator的叠加

(1) 用法

def decorator1(func):
    def dec(*args):
        print 'd1 pre'
        result = func(*args)
        print 'd1 post'
        return result
    return dec

def decorator2(func):
    def dec(*args):
        print 'd2 pre'
        result = func(*args)
        print 'd2 post'
        return result
    return dec

@decorator1
@decorator2
def test(name):
    print name

test('test') #out: d1 pre/d2 pre/test/d1 post/d2 post

(2) 原理

@decorator1
@decorator2
def test(name):
    print name

和上面的类似,内部原理是:

test = decorator1(decorator2(test))

注意decorator1(decorator2(test)),不是说先执行decorator2(test),再执行decorator1。

而是先把decorator2(test)作为参数,最先执行decorator1,然后再执行decorator2.。


参考文章:http://thecodeship.com/patterns/guide-to-python-function-decorators/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值