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

如何在Python类中动态修改装饰器参数值

动态替换装饰器参数的解决方案

问题核心:装饰器是在类定义阶段执行的,此时类的实例还未创建,self.name的值无法传递给装饰器参数。要实现根据实例化时传入的name动态修改装饰器的name参数,需要延迟参数的绑定时机。

方案一:动态装饰器工厂(调用时绑定)

通过自定义装饰器工厂,在方法被调用时从实例中获取动态的name值,再应用traceable装饰器:

import openai
from langsmith.run_helpers import traceable
from typing import Any

def dynamic_traceable(run_type, name_getter=None):
    def decorator(func):
        def wrapper(self, *args, **kwargs):
            # 从实例中获取动态name
            name = name_getter(self) if name_getter else func.__name__
            # 动态应用traceable装饰器并执行方法
            traced_func = traceable(run_type=run_type, name=name)(func)
            return traced_func(self, *args, **kwargs)
        return wrapper
    return decorator

class LangSmithClass:
    def __init__(self, name):
        self.name = name

    @traceable(run_type="llm", name="openai.ChatCompletion.create")
    def my_llm(self, *args: Any, **kwargs: Any) -> dict:
        return openai.ChatCompletion.create(*args, **kwargs)

    @traceable(run_type="chain")
    def my_chain(self, prompt: str) -> str:
        messages = [
            {"role": "system", "content": "You are an AI Assistant. "},
            {"role": "user", "content": prompt},
        ]
        return self.my_llm(model="gpt-3.5-turbo", messages=messages)

    @dynamic_traceable(run_type="chain", name_getter=lambda self: self.name)
    def my_chat_bot(self, text: str) -> str:
        generated = self.my_chain(text)
        return generated

# 测试
LangSmithClass("ABC").my_chat_bot("how are you")
LangSmithClass("XYZ").my_chat_bot("how are you")

优缺点:实现简单,但每次调用方法都会重新执行一次装饰器逻辑,性能略有损耗,适合调用频率不高的场景。

方案二:实例化时重新装饰(更高效)

将原方法的逻辑抽离为私有方法,在类的__init__方法中,根据当前实例的name重新应用traceable装饰器,并替换原方法:

import openai
from langsmith.run_helpers import traceable
from typing import Any

class LangSmithClass:
    def __init__(self, name):
        self.name = name
        # 用实例的name重新装饰私有方法,替换公共方法
        self.my_chat_bot = traceable(run_type="chain", name=self.name)(self._my_chat_bot_impl)

    @traceable(run_type="llm", name="openai.ChatCompletion.create")
    def my_llm(self, *args: Any, **kwargs: Any) -> dict:
        return openai.ChatCompletion.create(*args, **kwargs)

    @traceable(run_type="chain")
    def my_chain(self, prompt: str) -> str:
        messages = [
            {"role": "system", "content": "You are an AI Assistant. "},
            {"role": "user", "content": prompt},
        ]
        return self.my_llm(model="gpt-3.5-turbo", messages=messages)

    # 原方法逻辑作为私有实现
    def _my_chat_bot_impl(self, text: str) -> str:
        generated = self.my_chain(text)
        return generated

# 测试
LangSmithClass("ABC").my_chat_bot("how are you")
LangSmithClass("XYZ").my_chat_bot("how are you")

优缺点:仅在实例化时执行一次装饰逻辑,性能更优,是推荐的解决方案。如果traceable装饰器保留了原函数的__wrapped__属性,也可以直接获取原方法而不用抽离私有方法:

def __init__(self, name):
    self.name = name
    # 获取原方法(依赖traceable设置__wrapped__属性)
    original_func = self.my_chat_bot.__wrapped__
    self.my_chat_bot = traceable(run_type="chain", name=self.name)(original_func)

# 保留原装饰器写法
@traceable(run_type="chain")
def my_chat_bot(self, text: str) -> str:
    generated = self.my_chain(text)
    return generated

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:14:57