如何在Python中获取枚举值的文档字符串?
获取Python Enum成员的文档字符串
问题核心
Python标准Enum类的成员是类的实例,它们的__doc__属性会继承自所属Enum类的文档,无法直接获取成员自身的注释。而IDE能显示成员的文档,是因为它们通过静态代码解析实现,而非运行时读取属性。
实现方法
以下是几种在运行时获取Enum成员文档字符串的可行方案:
1. 静态解析源代码(无需修改Enum定义)
利用ast模块解析源代码的抽象语法树,提取枚举成员赋值语句后的注释:
import ast import inspect from enum import Enum def get_enum_member_docs(enum_cls): doc_map = {} # 获取枚举类的源代码 source = inspect.getsource(enum_cls) tree = ast.parse(source) # 遍历AST找到目标Enum类的定义 for node in ast.walk(tree): if isinstance(node, ast.ClassDef) and node.name == enum_cls.__name__: for idx, item in enumerate(node.body): # 找到成员赋值语句 if isinstance(item, ast.Assign): # 检查下一个节点是否是注释字符串 if idx + 1 < len(node.body): next_node = node.body[idx + 1] if (isinstance(next_node, ast.Expr) and isinstance(next_node.value, ast.Constant) and isinstance(next_node.value.value, str)): # 提取成员名称和对应的文档 for target in item.targets: if isinstance(target, ast.Name): doc_map[target.id] = next_node.value.value return doc_map # 示例Enum class Colors(Enum): """Colors we know...""" RED = 1 """The color of apples""" GREEN = 2 """The color of grass""" BLUE = 3 """The color of sky""" # 使用示例 member_docs = get_enum_member_docs(Colors) print(member_docs['RED']) # 输出: The color of apples
2. 自定义Enum元类(自动绑定文档到成员)
通过自定义元类,在Enum类创建时自动收集成员的注释并绑定到成员的自定义属性:
import ast import inspect from enum import Enum, EnumMeta class DocEnumMeta(EnumMeta): def __new__(metacls, clsname, bases, namespace): doc_map = {} # 解析当前模块的源代码 module = inspect.getmodule(namespace['__module__'] if '__module__' in namespace else clsname) if module: source = inspect.getsource(module) tree = ast.parse(source) # 定位目标Enum类 for node in ast.walk(tree): if isinstance(node, ast.ClassDef) and node.name == clsname: for idx, item in enumerate(node.body): if isinstance(item, ast.Assign): if idx + 1 < len(node.body): next_node = node.body[idx + 1] if (isinstance(next_node, ast.Expr) and isinstance(next_node.value, ast.Constant) and isinstance(next_node.value.value, str)): for target in item.targets: if isinstance(target, ast.Name): doc_map[target.id] = next_node.value.value # 创建Enum类 enum_cls = super().__new__(metacls, clsname, bases, namespace) # 给成员添加_doc属性 for name, member in enum_cls.__members__.items(): if name in doc_map: setattr(member, '_doc', doc_map[name]) return enum_cls # 使用自定义元类的Enum class Colors(Enum, metaclass=DocEnumMeta): """Colors we know...""" RED = 1 """The color of apples""" GREEN = 2 """The color of grass""" BLUE = 3 """The color of sky""" # 使用示例 print(Colors.RED._doc) # 输出: The color of apples
3. 使用第三方库aenum(原生支持成员文档)
aenum是标准enum的扩展库,原生支持为枚举成员指定文档字符串:
from aenum import Enum class Colors(Enum): """Colors we know...""" RED = 1, 'The color of apples' GREEN = 2, 'The color of grass' BLUE = 3, 'The color of sky' # 使用示例 print(Colors.RED.__doc__) # 输出: The color of apples
关于IDE智能提示的说明
PyCharm、VS Code等IDE的智能提示,是通过静态代码分析实现的:它们直接解析源代码的AST结构,识别枚举成员赋值语句后的注释文本,无需运行代码即可提取并显示这些文档。这就是为什么IDE能显示成员文档,但标准Enum运行时无法直接通过__doc__获取的原因。
内容的提问来源于stack exchange,提问作者Peter Bosch
相关产品推荐
相关产品推荐

