`
_wyh
  • 浏览: 59361 次
社区版块
存档分类
最新评论

python装饰器

阅读更多

由于没有真正实用经验,所以只记录基本用法,以免经常不用忘的太彻底。

 

简单说,decorator也是一个函数,可以在不更改另一个函数的情况下,改变或增加另一个函数的功能。

1,不使用装饰器。

 

def decoTest(func):
    print("before")
    func()
    print("after")

def test():
    print('Hello, World')

decoTest(test)

   为了达到在test()执行前后分别执行不同语句功能,将test作为参数,传入decoTest中。之后需要调用decoTest函数,如果想直接调用test来达到这个目的,需要使用装饰器。

 

 

2,使用@语法

 

def decoTest(func):
    print("before")
    func()
    print("after")
    return func

@decoTest
def test():
    print('Hello, World')


test

   在decoTest中增加了返回值,返回传入的函数。相当于执行了decoTest(test)。所以结果与上面的相同。所以如果最后调用的是test(),将多输出一个Hello, World。

 

 

3,为解决2中调用test()多输出一个Hello, World。对decoTest进行包装,使它返回一个函数。

 

def decoTest(func):
    def wrapper():
        print('before')
        func()
        print('after')
    return wrapper

@decoTest
def test():
    print('Hello, World')


test()

   此时的输出不会再多一行。因为返回的是函数,执行test()相当是将test传入decoTest中,decoTest返回wrapper,此时因为执行的是test(),所以最终会执行wrapper()。

 

 

4,解决带参数函数的装饰。

 

def decoTest(func):
    def wrapper(a, b):
        print('before')
        func(a, b)
        print('after')
    return wrapper

@decoTest
def test(a, b):
    print('a + b =', a + b)


test(2, 9)

    结果为:

before
a + b = 11
after

    因为装饰器函数返回的是一个函数,所以可以接受参数。所以2,9也传入了wrapper中,所以返回正确。

 

 

5,使用*, **来解决参数数量的不确定性。

 

def decoTest(func):
    def wrapper(*args, **kwargs):
        print('before')
        func(*args, **kwargs)
        print('after')
    return wrapper

@decoTest
def test(a, b, c, d):
    print('sum =', a + b + c + d)

@decoTest
def test2(*args, **kwargs):
    print("%s, %s" % (args, kwargs))

test(2, 9, 10, 23)

test2(2, 3, 5, a = 5, c = 2)

   test和test2都实现了在本身函数之前之后分别输出某个语句。

 

 

6,装饰器函数也可以传入参数。

 

def deco(arg) :
    def decoTest(func):
        def wrapper(*args, **kwargs):
            print('before', arg)
            func(*args, **kwargs)
            print('after', arg)
        return wrapper
    return decoTest


@deco("test")
def test(a, b, c, d):
    print('sum =', a + b + c + d)

@deco("test2")
def test2(*args, **kwargs):
    print("%s, %s" % (args, kwargs))

test(2, 9, 10, 23)

test2(2, 3, 5, a = 5, c = 2)

    输出结果为:

before test
sum = 44
after test
before test2
(2, 3, 5), {'c': 2, 'a': 5}
after test2

   装饰器函数里面嵌套定义了两个函数。例子中装饰器函数为deco,deco返回的是函数decoTest,decoTest有一个函数参数,装饰器返回的函数可以接受另一个函数,而decoTest又返回了wrapper函数。所以decoTest函数可以接受多个参数并最终输出。

 

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics