【问题标题】:How to get a list of a Python class' variables with their docstring documentation如何使用其文档字符串文档获取 Python 类的变量列表
【发布时间】:2020-11-05 04:46:13
【问题描述】:

如何从 Python 类或数据类中获取类成员变量及其文档字符串描述的列表?

我有这个数据类

@dataclass
class MyDataClass(BaseDataClass):
    """
    :param var1: Description for var1
    :param var2: Description for var2
    """
    var1: int
    var2: int

我希望能够为它获取这些信息:

{
  'var1': ('int', 'Description for var1'), 
  'var2': ('int', 'Description for var2')
}

【问题讨论】:

    标签: python-3.x class introspection


    【解决方案1】:

    为了获取类成员变量的列表及其描述,我使用类方法创建了一个空数据类

    get_user_parameters_dict(cls)
    

    解析类文档字符串并返回包含成员名称、类型和描述的管道。 由于文档字符串不是自动生成的,因此您需要按照以下代码中的示例进行操作。主要部分的输出是

    输出:

    This does not work for a class without properties
    This class is probably BaseDataClass. Is it? Actual name: BaseDataClass
    
    var1: int - Description for var1
    var2: int - Description for var2
    
    
    from dataclasses import dataclass
    from typing import Dict, Tuple
    import re
    

    代码:

    @dataclass
    class BaseDataClass:
        """
        Example of how to docstring var1 and var2, so reflection works here
        :param var1: Description for var1
        :param var2: Description for var2
        """
    
        # Example of declaring properties var1 and var2
        # var1: int
        # var2: int
    
        @classmethod
        def get_user_parameters_dict(cls) -> Dict[str, Tuple[str, str]]:
            properties_descriptions: Dict[str, str] = {}
            regex = r":param *(.*): *(.*)"
            from typing import Generator
            matches: Generator[re.Match, None, None] = re.finditer(regex, cls.__doc__, re.MULTILINE)
            for match in matches:
                prop_name: str = match.groups()[0]
                prop_description: str = match.groups()[1]
                properties_descriptions[prop_name] = prop_description
    
            dataclass_properties: Dict[str, Tuple[str, str]] = {}
            try:
                dataclass_annotations: Dict[str, object] = cls.__dict__['__annotations__']
                for prop_name, property_type in dataclass_annotations.items():
                    dataclass_properties[prop_name] = (property_type.__name__, properties_descriptions[prop_name])
    
                return dataclass_properties
            except KeyError as ke:
                print('This does not work for a class without properties')
    
    
    
    @dataclass
    class MyDataClass(BaseDataClass):
        """
        :param var1: Description for var1
        :param var2: Description for var2
        """
        var1: int
        var2: int
    
    
    if __name__ == '__main__':
        a = BaseDataClass
        try:
            for property_name, property_metadata in BaseDataClass.get_user_parameters_dict().items():
                print(f'{property_name}: {property_metadata[0]} - {property_metadata[1]}')
        except AttributeError as ae:
            print(f'This class is probably TestuserProperties. Is it? Actual name: {BaseDataClass.__name__}')
    
        print()
    
        for property_name, property_metadata in MyDataClass.get_user_parameters_dict().items():
            print(f'{property_name}: {property_metadata[0]} - {property_metadata[1]}')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-07
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 2019-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多