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

如何使classmethod适配__getitem__?保留Permissions类__getitem__并优化as_list

解决方案

当然可以,这里有两种实用方案,既能保留__getitem__的实例调用能力,又能让as_list直接以Permissions.as_list()的形式调用,无需先实例化类。

方案一:抽取公共权限查找逻辑

核心思路是把__getitem__里的权限查找和异常抛出逻辑抽成一个类方法,让实例方法和类方法复用同一逻辑,避免代码重复。

修改后的完整代码:

from enum import Enum

class Permission(Enum):
    CAN_DELETE = 'can_delete'
    CAN_EDIT = 'can_edit'

class UserType(Enum):
    ADMIN = 'admin'
    GUEST = 'guest'

PERMISSIONS = {
    UserType.ADMIN: [Permission.CAN_DELETE, Permission.CAN_EDIT],
}

class UnknownUserTypeError(Exception):
    pass

class Permissions:
    permissions = PERMISSIONS

    @classmethod
    def _get_permissions(cls, user_type: UserType):
        try:
            return cls.permissions[user_type]
        except KeyError:
            raise UnknownUserTypeError

    def __getitem__(self, user_type: UserType):
        return self._get_permissions(user_type)

    @classmethod
    def as_list(cls, user_type: UserType):
        return [p.value for p in cls._get_permissions(user_type)]

# 测试调用
try:
    perms = Permissions.as_list(UserType.GUEST)
    print(perms)
except UnknownUserTypeError:
    print("未知用户类型")

# 原有的实例下标访问依然可用
admin_perms_instance = Permissions()[UserType.ADMIN]
print([p.value for p in admin_perms_instance])

说明

  • 新增类方法_get_permissions,封装了权限查找和异常处理的核心逻辑
  • 实例方法__getitem__调用这个类方法,保持原有的实例下标访问功能(比如Permissions()[UserType.ADMIN]依然有效)
  • as_list直接调用_get_permissions,完全符合你想要的Permissions.as_list()API风格

方案二:实现类级别的__class_getitem__

如果你想额外让类本身支持下标操作(比如Permissions[UserType.ADMIN]),可以实现__class_getitem__特殊方法,这样as_list里就能直接用cls[user_type]了。

修改后的完整代码:

from enum import Enum

class Permission(Enum):
    CAN_DELETE = 'can_delete'
    CAN_EDIT = 'can_edit'

class UserType(Enum):
    ADMIN = 'admin'
    GUEST = 'guest'

PERMISSIONS = {
    UserType.ADMIN: [Permission.CAN_DELETE, Permission.CAN_EDIT],
}

class UnknownUserTypeError(Exception):
    pass

class Permissions:
    permissions = PERMISSIONS

    def __getitem__(self, user_type: UserType):
        try:
            return self.permissions[user_type]
        except KeyError:
            raise UnknownUserTypeError

    @classmethod
    def __class_getitem__(cls, user_type: UserType):
        try:
            return cls.permissions[user_type]
        except KeyError:
            raise UnknownUserTypeError

    @classmethod
    def as_list(cls, user_type: UserType):
        return [p.value for p in cls[user_type]]

# 测试调用
try:
    perms = Permissions.as_list(UserType.GUEST)
    print(perms)
except UnknownUserTypeError:
    print("未知用户类型")

# 新增的类下标访问功能
admin_perms_class = Permissions[UserType.ADMIN]
print([p.value for p in admin_perms_class])

# 原有的实例下标访问依然可用
admin_perms_instance = Permissions()[UserType.ADMIN]
print([p.value for p in admin_perms_instance])

说明

  • __class_getitem__是Python 3.7+支持的特殊方法,专门用于实现类的下标操作
  • 此方案既保留了实例的__getitem__功能,又新增了类级别的下标访问能力
  • as_list里直接使用cls[user_type],完全符合你的API偏好

方案选择

  • 如果你只需要满足Permissions.as_list()的调用需求,方案一更简洁,且避免了逻辑重复
  • 如果你希望类本身也能像实例一样用下标访问权限,方案二更适合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:55:29