且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Python:decorator装饰器的使用示例

更新时间:2022-08-17 15:06:38

定义一个装饰器


def decorator(func):
    def wrapper(*arg, **kwargs):
        print("before")

        ret = func(*arg, **kwargs)

        print("after")
        return ret

    return wrapper

使用示例

# -*- coding: utf-8 -*-


# 作用于普通方法
@decorator
def foo(name):
    print('my name is:', name)


class Foo(object):
    # 作用于实例方法
    @decorator
    def foo(self, name):
        print('my name is:', name)

    # 作用于类方法
    @classmethod
    @decorator
    def class_foo(cls, name):
        print('my name is:', name)

    # 作用于静态方法
    @staticmethod
    @decorator
    def static_foo(name):
        print('my name is:', name)

if __name__ == '__main__':
    foo('Tom')

    Foo().foo('Tom')

    Foo.class_foo('Tom')

    Foo.static_foo('Tom')

"""
4中方式都可以正常执行,输入如下
before
my name is: Tom
after
"""

如果把装饰器函数参数修改了


def decorator(func):
    def wrapper(name):
        print("before")

        # ret = func(*arg, **kwargs)
        
        # 取消原来的不定参数,写为固定参数
        ret = func(name)

        print("after")
        return ret

    return wrapper

执行结果

# 普通函数可以正常执行
foo('Tom')

# 静态方法可以正常执行
Foo.static_foo('Tom')

# 实例方法报错
Foo().foo('Tom')
# TypeError: wrapper() takes 1 positional argument but 2 were given

# 类方法报错
Foo.class_foo('Tom')
# TypeError: wrapper() takes 1 positional argument but 2 were given

综上,一般情况下需要写成不定参数的形式,兼容性更强

参考

详解Python的装饰器