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

如何在Account类各方法中优雅实现__authorized权限校验?

问题描述

现有一个Account类,包含私有属性__authorized,调用get()方法会获取账户数据并将__authorized设为True。另外有method_1、method_2、method_3等多个账户操作方法,要求每个操作方法执行前都要校验__authorized:若为False则抛出异常。

目前尝试了两种方案,但都比较繁琐:

方案1:手动在每个方法中写入校验逻辑

class Account:
    def __init__(self):
        self.__authorized = False
    
    def get(self):
        # 执行获取账户数据的操作
        self.__authorized = True

    def method_1(self):
        if not self.__authorized:
            raise Exception("The account is not authorized with the get method!")

    def method_2(self):
        if not self.__authorized:
            raise Exception("The account is not authorized with the get method!")

    def method_3(self):
        if not self.__authorized:
            raise Exception("The account is not authorized with the get method!")

这种方案需要重复编写相同的校验代码,维护成本高,容易遗漏。

方案2:使用装饰器包裹需要校验的方法

def check_account_authorized(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authorized():
            raise Exception("The account is not authorized with the get method!")
        return func(*args, **kwargs)
    return wrapper


class Account:
    def __init__(self):
        self.__authorized = False

    def get(self):
        # 执行获取账户数据的操作
        self.__authorized = True

    @check_account_authorized
    def method_1(self):
        pass

    @check_account_authorized
    def method_2(self):
        pass

    @check_account_authorized
    def method_3(self):
        pass

    def is_authorized(self):
        return self.__authorized

这种方案比手动写校验更优,但仍需给每个方法添加装饰器,方法数量多时依然繁琐,且新增方法容易忘记加装饰器。


更优雅的解决方案

可以利用Python的__getattribute__方法,它会拦截对类实例属性(包括方法)的所有访问请求,我们可以在这个方法中统一处理校验逻辑:

class Account:
    def __init__(self):
        self.__authorized = False
        # 定义需要校验的方法列表
        self._protected_methods = {'method_1', 'method_2', 'method_3'}

    def get(self):
        # 执行获取账户数据的操作
        self.__authorized = True

    def method_1(self):
        print("执行method_1")

    def method_2(self):
        print("执行method_2")

    def method_3(self):
        print("执行method_3")

    def __getattribute__(self, name):
        # 获取目标属性/方法
        attr = super().__getattribute__(name)
        # 仅对指定方法执行校验
        if name in self._protected_methods and callable(attr):
            if not self.__authorized:
                raise Exception("The account is not authorized with the get method!")
        return attr

方案优势

  • 无需重复编写校验代码,也不用逐个添加装饰器,一次配置即可覆盖所有目标方法
  • 新增需要校验的方法时,只需在_protected_methods集合中添加方法名即可,维护更便捷
  • 校验逻辑集中在一处,后续修改规则只需调整__getattribute__中的代码

除此之外,也可以使用类装饰器批量为方法添加校验,或者用元类在类创建时自动为指定方法绑定校验逻辑,但__getattribute__的方式更直观简洁,适合这类场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:28:15