python 装饰器

2019-05-30  本文已影响0人  都江堰古巨基

装饰器的主要作用是将函数增加一些功能的,它不能改变函数本身,只是在原来的函数上增加功能
举个栗子:现在我们有一个函数返回0-10的列表,但我们现在需要在这个列表里面返回0-100中所有的偶数,用装饰器可以这么实现:

def myDecorator(func):
    def warpper(*args,**kwargs):
        my_list = func()
        return [i for i in my_list if i%2==0]
    return warpper

@myDecorator
def useDecorator():
    return [i for i in range(10)]

def notUseDecorator():
    return [i for i in range(10)]

print(useDecorator())  # [0,2,4,6,8]
print(notUseDecorator()) # [0,1,2,3,4,5,6,7,8,9]

1、最简单的装饰器

# -*- coding:utf-8 -*-
'''示例1: 使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
但发现新函数只在第一次被调用,且原函数多调用了一次'''

def deco(func):
    print("before myfunc() called.")
    func()
    print("after myfunc() called.")
    return func

@deco
def myfunc():
    print(" myfunc() called.")

myfunc()

# 输出结果:
before myfunc() called.
myfunc() called.
after myfunc() called.

这样的问题是装饰器只会被调用一次,即以后使用函数myfunc()输出的结果为:myfunc() called.

2、确保装饰器被调用

# -*- coding:utf-8 -*-
def deco(func):
    def _deco():
        print("before myfunc() called.")
        func()
        print("  after myfunc() called.")
        # 不需要返回func,实际上应返回原函数的返回值
    return _deco

@deco
def myfunc():
    print(" myfunc() called.")

myfunc()

# 输出结果:
before myfunc() called.
myfunc() called.
after myfunc() called.

3、对带参数的函数进行装饰

# -*- coding:utf-8 -*-
'''示例5: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象'''

def deco(func):
    def _deco(a, b):
        print("before myfunc() called.")
        ret = func(a, b)
        print("after myfunc() called. result: %s" % ret)
        return ret
    return _deco

@deco
def myfunc(a, b):
    print(" myfunc(%s,%s) called." % (a, b))
    return a + b

myfunc(1, 2)
before myfunc() called.
myfunc(1,2) called.
after myfunc() called. result: 3
3
# 输出结果:

4、让装饰器带上参数

# -*- coding:utf-8 -*-
'''示例: 在3的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些'''

def deco(arg):
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, arg))
            func()
            print("after %s called [%s]." % (func.__name__, arg))
        return __deco
    return _deco

@deco("mymodule")
def myfunc():
    print(" myfunc() called.")

@deco("module2")
def myfunc2():
    print("myfunc2() called.")

myfunc()
myfunc2()

# 输出结果:
before myfunc called [mymodule].
myfunc() called.
after myfunc called [mymodule].

before myfunc2 called [module2].
myfunc2() called.
after myfunc2 called [module2].
上一篇下一篇

猜你喜欢

热点阅读