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

如何访问Python中按PEP258定义的实例属性文档字符串?

如何访问Python实例属性的文档字符串

首先要明确:PEP 258中提到的在__init__里给实例属性写文档字符串的写法,Python解释器并不会自动将这个字符串和实例属性绑定。你看到instance.i?显示str的文档,是因为self.i被赋值为字符串实例,而那个独立的文档字符串字面量只是__init__函数里的无关联语句,并没有和self.i建立绑定关系。

以下是几种可行的解决方案:

1. 使用dataclass(推荐,Python 3.7+)

如果是静态实例属性,dataclass原生支持字段的文档字符串,且能通过标准工具访问;动态属性则可以结合包装类处理:

from dataclasses import dataclass
import inspect

@dataclass
class AClass:
    c: str = 'class attribute'
    """This is AClass.c's docstring."""

    def __post_init__(self):
        # 用包装类给动态属性添加文档
        class AttrWrapper:
            def __init__(self, value, doc):
                self.value = value
                self.__doc__ = doc
            def __str__(self):
                return str(self.value)
        
        self.i = AttrWrapper('instance attribute', "This is self.i's docstring.")

instance = AClass()
# 访问类属性文档
print(inspect.getdoc(AClass.c))
# 访问动态实例属性文档
print(instance.i.__doc__)

2. 手动包装实例属性

通过自定义包装类给动态属性添加__doc__,避开内置类型无法添加属性的限制:

class AClass:
    c = 'class attribute'
    """This is AClass.c's docstring."""

    def __init__(self):
        class WrappedAttr:
            def __init__(self, value, doc):
                self.value = value
                self.__doc__ = doc
            # 实现魔术方法让包装类行为贴近原类型
            def __repr__(self):
                return repr(self.value)
            def __eq__(self, other):
                return self.value == other

        self.i = WrappedAttr('instance attribute', "This is self.i's docstring.")

instance = AClass()
print(instance.i.__doc__)  # 输出目标文档字符串

3. 解析源代码提取文档(不推荐,hacky方式)

如果一定要保留PEP 258的写法,可以通过解析__init__的源代码,提取赋值语句后的字符串:

import ast
import inspect

class AClass:
    def __init__(self):
        self.i = 'instance attribute'
        """This is self.i's docstring."""

# 提取并解析__init__的源代码
source_code = inspect.getsource(AClass.__init__)
tree = ast.parse(source_code)

# 遍历AST节点找到目标文档
for idx, node in enumerate(tree.body):
    if isinstance(node, ast.Assign) and len(node.targets) == 1:
        target = node.targets[0]
        if isinstance(target, ast.Attribute) and target.attr == 'i':
            if idx + 1 < len(tree.body):
                next_node = tree.body[idx+1]
                if isinstance(next_node, ast.Expr) and isinstance(next_node.value, ast.Constant):
                    print(next_node.value.value)  # 输出目标文档字符串

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:56:00