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

如何基于__init__参数控制对象实例的指定方法访问权限

实现方案

你之前对装饰器的适用场景存在误解:装饰器本身的绑定逻辑确实在类定义阶段执行,但装饰器包裹的校验逻辑会在方法被实例调用时才运行,此时实例已经完成初始化,可以正常获取实例属性,因此装饰器是完全适用的,以下是两种符合DRY原则的实现方案:

方案1:通用方法装饰器(推荐,灵活度高)

适合需要零散限制部分方法的场景,只需要给目标方法加装饰器即可,无需修改类的核心逻辑:

# 通用限制装饰器
def restrict_if(flag_attr: str, error_cls=Exception, error_msg: str = "当前方法无访问权限"):
    def decorator(method):
        def wrapper(self, *args, **kwargs):
            # 调用方法时才校验实例属性
            if getattr(self, flag_attr, False):
                raise error_cls(error_msg)
            return method(self, *args, **kwargs)
        return wrapper
    return decorator

# 业务类实现
class NewClass:
    def __init__(self, has_non_available_method: bool):
        self.has_non_available_method = has_non_available_method

    @restrict_if("has_non_available_method", error_cls=PermissionError)
    def some_method(self):
        return "方法正常执行"

    @restrict_if("has_non_available_method", error_msg="该功能已被禁用")
    def another_method(self):
        return "另一个方法正常执行"

测试效果:

# 允许访问的实例
obj_allow = NewClass(has_non_available_method=False)
print(obj_allow.some_method()) # 输出:方法正常执行

# 禁止访问的实例
obj_deny = NewClass(has_non_available_method=True)
obj_deny.some_method() # 抛出 PermissionError: 当前方法无访问权限

方案2:重写__getattribute__魔术方法(适合批量限制场景)

如果需要限制的方法数量多,可以统一维护限制列表,无需逐个加装饰器:

class NewClass:
    # 统一维护需要限制的方法名列表
    _RESTRICTED_METHODS = {"some_method", "another_method"}

    def __init__(self, has_non_available_method: bool):
        self.has_non_available_method = has_non_available_method

    def __getattribute__(self, name: str):
        # 注意这里要用super调用避免无限递归
        restrict_flag = super().__getattribute__("has_non_available_method")
        restricted_methods = super().__getattribute__("_RESTRICTED_METHODS")
        if restrict_flag and name in restricted_methods:
            raise PermissionError("当前方法无访问权限")
        return super().__getattribute__(name)

    def some_method(self):
        return "方法正常执行"

    def another_method(self):
        return "另一个方法正常执行"

    def free_method(self):
        return "不受限制的方法"

测试效果:

obj_deny = NewClass(has_non_available_method=True)
print(obj_deny.free_method()) # 输出:不受限制的方法
obj_deny.some_method() # 抛出 PermissionError: 当前方法无访问权限

内容的提问来源于stack exchange,提问作者IO.PY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 08:12:02