bobdu.cc

Follow me on GitHub

装饰器

不带参数的装饰器

from functools import wraps

def log(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print('函数执行前的日志信息:')
        ret = func()
        print('函数执行结束时的日志信息:')
        return ret
    return wrapper


@log
def print_123():
    print('123')
    return 123

print_123()
print(print_123.__name__)
函数执行前的日志信息:
123
函数执行结束时的日志信息:
print_123

带参数的装饰器

from functools import wraps

def log(text):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('函数执行前的日志信息:', text)
            ret = func()
            print('函数执行结束时的日志信息:', text)
            return ret
        return wrapper
    return decorator


@log('---')
def print_123():
    print('123')
    return 123

print_123()
print(print_123.__name__)
函数执行前的日志信息: ---
123
函数执行结束时的日志信息: ---
print_123

同时支持两种写法的装饰器

from functools import wraps

def log(text):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('函数执行前的日志信息:', text)
            ret = func()
            print('函数执行结束时的日志信息:', text)
            return ret
        return wrapper
    if not isinstance(text, str):
        func = text
        text = ''
        return decorator(func)
    return decorator


@log
def print_123():
    print('123')
    return 123

print_123()
print(print_123.__name__)

@log('---')
def print_456():
    print('456')
    return 456

print_456()
print(print_456.__name__)

目前并没有太好的写法 基本思路都是

判断text传入的是本来打算给装饰器的参数还是装饰器省略了参数而把被装饰函数错误的传递给了text变量

如果是后者 把被装饰函数还给func变量 并且将text变量还原为默认值

但是这些写法都不够优雅,缺乏通用性