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

参数化密码装饰器实现问题:不可修改被装饰函数

问题分析

你的代码存在两个核心错误:

  1. 逻辑倒置:你试图用原函数的返回值和密码对比,这完全搞反了——应该验证用户传入的密码和装饰器参数是否匹配,而非原函数的输出。
  2. 参数传递错误:你直接把所有调用参数传给原函数,导致原函数(比如add)收到多余的密码参数,触发TypeError。
解决方案

我们需要重新设计装饰器逻辑:先从调用参数中提取密码验证,验证通过后,把去除密码后的参数传给原函数。以下提供两种实用实现:

方式一:约定密码为第一个位置参数

适配你示例中add("h",1,2)的调用方式:

def password(pswd):
    def decorator(f):
        def wrapper(*args, **kwargs):
            # 检查是否传入密码
            if not args:
                raise ValueError("Password not provided")
            # 提取第一个位置参数作为密码
            input_pswd = args[0]
            if input_pswd != pswd:
                raise ValueError("Invalid password")
            # 去除密码后,将剩余参数传给原函数
            return f(*args[1:], **kwargs)
        return wrapper
    return decorator

# 使用示例
@password("h")
def add(a, b):
    return a + b

# 正确调用
print(add("h", 1, 2))  # 输出3
# 错误调用会抛出ValueError
# add("wrong", 1, 2)
# add(1, 2)

方式二:约定密码通过关键字参数传入(更灵活)

避免密码和原函数位置参数冲突,推荐使用:

def password(pswd):
    def decorator(f):
        def wrapper(*args, **kwargs):
            # 从关键字参数提取密码,同时移除该参数
            input_pswd = kwargs.pop("password", None)
            if input_pswd is None:
                raise ValueError("Password not provided")
            if input_pswd != pswd:
                raise ValueError("Invalid password")
            # 传递剩余参数给原函数
            return f(*args, **kwargs)
        return wrapper
    return decorator

# 使用示例
@password("h")
def add(a, b):
    return a + b

# 正确调用
print(add(1, 2, password="h"))  # 输出3
# 错误调用会抛出ValueError
# add(1, 2, password="wrong")
# add(1, 2)

进阶:同时支持位置参数和关键字参数

如果需要兼容两种传参方式:

def password(pswd):
    def decorator(f):
        def wrapper(*args, **kwargs):
            input_pswd = None
            # 优先从关键字参数提取
            if "password" in kwargs:
                input_pswd = kwargs.pop("password")
            elif args:
                # 没有关键字参数则取第一个位置参数
                input_pswd = args[0]
                args = args[1:]
            else:
                raise ValueError("Password not provided")
            
            if input_pswd != pswd:
                raise ValueError("Invalid password")
            
            return f(*args, **kwargs)
        return wrapper
    return decorator

# 两种调用方式都支持
@password("h")
def add(a, b):
    return a + b

print(add("h", 1, 2))  # 输出3
print(add(1, 2, password="h"))  # 输出3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:53:15