You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行函数前查看装饰器参数默认值?及装饰器解耦实现

问题描述

我有一系列使用装饰器标记其在流水线中所属类别(入口、处理、出口等)的函数,示例如下:

@custom_task(task_type=TaskType.Ingress)
def my_task(<arg1>, <arg2>, ...):
    ...

以下是custom_task装饰器的简化版本:

def custom_task(task_type=TaskType.Unknown):
    def wrapper(func):
        def executor(*args, **kwargs):
            func.__task_type__ = task_type
            func(*args, **kwargs)
        return executor
    return wrapper

我知道必须先运行代码才能创建/填充__task_type__属性,但有没有办法(使用inspect或其他库)在运行my_task前查看my_task的custom_task装饰器中task_type参数的默认值?

补充说明

实际上,该装饰器除了为函数分配枚举属性外,还包含异常日志功能,示例如下:

def custom_task(task_type=TaskType.Unknown):
    def wrapper(func):
        def executor(*args, **kwargs):
            try:
                func(*args, **kwargs)
            except Exception as e:
                # 数据库中记录异常的逻辑
                ...
        func.__task_type__ = task_type
        return executor
    return wrapper

或许将错误日志与属性赋值行为解耦,使用两个独立装饰器会更合理?

最终解决方案

将异常日志和属性赋值的行为解耦,既能实现运行前获取__task_type__属性的需求,又能保留异常日志功能。最终实现代码如下:

使用示例

@custom_task(task_type=TaskType.Ingress)
@log_exceptions
def my_task(<arg1>, <arg2>, ...):
   ...

装饰器实现

_NO_ARG = object()

def custom_task(arg=_NO_ARG):
    if callable(arg):
        func = arg
        func.__task_type__ = TaskType.Unknown
        return func
    if arg is _NO_ARG:
        task_type = TaskType.Unknown
    else:
        task_type = arg
    def decorator(func):
        func.__task_type__ = task_type
        return func
    return decorator

def log_exceptions(func):
    def wrapper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except Exception as e:
            # 将异常记录到数据库的逻辑
            ...
    return wrapper

方案说明

  • 重构后的custom_task不再嵌套执行器逻辑,而是在装饰阶段直接为函数绑定__task_type__属性,无需运行函数就能获取该属性值。
  • 支持两种使用方式:带参数(@custom_task(task_type=xxx))和不带参数(@custom_task),后者会默认设置task_type为TaskType.Unknown。
  • 异常日志功能拆分到独立的log_exceptions装饰器中,职责单一,方便单独复用或调整。

内容的提问来源于stack exchange,提问作者BenBole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:01:24