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

如何在Python类中动态生成带指定ReasonOptions的send_otp方法?

动态生成OTP发送方法的解决方案

你可以通过类装饰器+方法规范映射的方式,自动生成所有重复的send_xxx_otp方法,避免手动编写冗余代码。以下是两种可行的实现方案:

方案1:基础版(统一参数名)

如果可以接受所有方法使用统一参数名(比如identifier),用闭包+装饰器就能快速实现:

from functools import partial
from your_module import ReasonOptions, Manager, BaseOtp

# 定义方法名与对应ReasonOptions的映射表
REASON_METHOD_MAP = {
    "send_forget_password_otp": ReasonOptions.FORGET_PASSWORD,
    "send_phone_number_activation_otp": ReasonOptions.PHONE_NUMBER_ACTIVATION,
    "send_two_step_auth_activation_otp": ReasonOptions.ENABLE_TWO_STEP_AUTH,
    "send_two_step_auth_deactivation_otp": ReasonOptions.DISABLE_TWO_STEP_AUTH,
    "send_change_user_identifier_otp": ReasonOptions.CHANGE_USER_IDENTIFIER,
}

def add_otp_methods(cls):
    for method_name, reason in REASON_METHOD_MAP.items():
        # 用partial捕获当前循环的reason,避免闭包变量共享问题
        def otp_method(self, identifier, r=reason):
            return self.send_otp(identifier, reason=r)
        # 设置方法名,保证调用和调试的可读性
        otp_method.__name__ = method_name
        # 添加类型提示
        otp_method.__annotations__ = {"identifier": str}
        # 将方法绑定到类
        setattr(cls, method_name, otp_method)
    return cls

# 应用装饰器自动生成方法
@add_otp_methods
class OtpBusinessLogicLayer(Manager, BaseOtp):
    pass

方案2:进阶版(保留原参数名与类型提示)

如果需要严格保留原代码中的参数名(比如phone_number、email)和类型提示,可以通过exec动态生成方法代码:

from your_module import ReasonOptions, Manager, BaseOtp

# 定义详细的方法规范:包含方法名、reason、参数名、参数类型
OTP_METHOD_SPECS = [
    {
        "method_name": "send_forget_password_otp",
        "reason": ReasonOptions.FORGET_PASSWORD,
        "param_name": "identifier",
        "param_type": str
    },
    {
        "method_name": "send_phone_number_activation_otp",
        "reason": ReasonOptions.PHONE_NUMBER_ACTIVATION,
        "param_name": "phone_number",
        "param_type": str
    },
    {
        "method_name": "send_two_step_auth_activation_otp",
        "reason": ReasonOptions.ENABLE_TWO_STEP_AUTH,
        "param_name": "email",
        "param_type": str
    },
    {
        "method_name": "send_two_step_auth_deactivation_otp",
        "reason": ReasonOptions.DISABLE_TWO_STEP_AUTH,
        "param_name": "email",
        "param_type": str
    },
    {
        "method_name": "send_change_user_identifier_otp",
        "reason": ReasonOptions.CHANGE_USER_IDENTIFIER,
        "param_name": "email",
        "param_type": str
    },
]

def add_otp_methods(cls):
    for spec in OTP_METHOD_SPECS:
        method_name = spec["method_name"]
        reason = spec["reason"]
        param_name = spec["param_name"]
        param_type = spec["param_type"]
        
        # 动态生成符合原代码结构的方法代码
        method_code = f"""
def {method_name}(self, {param_name}: {param_type.__name__}):
    return self.send_otp({param_name}, reason={reason})
"""
        # 执行代码并获取生成的方法
        local_namespace = {}
        exec(method_code, globals(), local_namespace)
        otp_method = local_namespace[method_name]
        # 将方法绑定到类
        setattr(cls, method_name, otp_method)
    return cls

# 应用装饰器自动生成方法
@add_otp_methods
class OtpBusinessLogicLayer(Manager, BaseOtp):
    pass

说明

  • 两种方案都无需手动编写每个send_xxx_otp方法,只需维护映射/规范表即可
  • 方案2完全保留原代码的参数名和类型提示,调用方式与原代码完全一致
  • 后续新增OTP场景时,只需在映射/规范表中添加新条目,就能自动生成对应方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:53:19