本文旨在提供一种使用 Python 反射机制获取类及其父类中所有声明或类型化的参数的方法。通过结合 inspect.get_annotations 和类的 __mro__ 属性,我们可以提取包括父类在内的所有类型注解,并将其组织成一个易于使用的字典。本文提供详细的代码示例和解释,帮助读者理解和应用这一技术。
Python 的 inspect 模块提供了强大的反射功能,其中 inspect.get_annotations 函数可以获取指定对象的类型注解。类的 __mro__ 属性则包含了类的继承关系,即方法解析顺序(Method Resolution Order)。结合这两个工具,我们可以遍历类的继承链,提取所有父类的类型注解。
以下是一个示例代码:
import inspect from typing import Any, Optional, Dict class Parent: parent_param: str parent_default: Optional[str] = None @classmethod def find_params_meta(cls) -> Dict[str, Any]: params_meta = {} for c in reversed(cls.__mro__): if hasattr(c, '__annotations__'): for k, v in inspect.get_annotations(c).items(): if k not in params_meta: # 避免子类覆盖父类同名参数的类型信息 params_meta[k] = {"types": [v]} if hasattr(cls, k) and getattr(cls, k) != inspect._empty: params_meta[k]["default"] = getattr(cls, k) return params_meta class Child(Parent): child_param: str _params_meta: Optional[Dict[str, Any]] = None def __init__(self, parent_param: str, child_param: str): self._params_meta = self.find_params_meta() self.child_param = child_param self.parent_param = parent_param def __getattr__(self, name): # 模拟未初始化的属性访问 raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'") # 实例化对象并打印结果 child_instance = Child("parent param", "child param") print(child_instance._params_meta) # 断言 expected_result = { "parent_param": {"types": [str]}, "parent_default": {"types": [str, type(None)], "default": None}, "child_param": {"types": [str]}, } assert child_instance._params_meta == expected_result
代码解释:
运行结果:
{'parent_param': {'types': [<class 'str'>]}, 'parent_default': {'types': [<class 'str'>, <class 'NoneType'>], 'default': None}, 'child_param': {'types': [<class 'str'>]}
通过结合 inspect.get_annotations 和 __mro__ 属性,我们可以方便地获取类及其父类的类型注解。这对于实现一些通用的工具函数,例如自动生成 API 文档、参数校验等非常有用。 在实际应用中,需要注意类型覆盖、性能和兼容性等问题。
以上就是获取类中所有声明或类型化的参数的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号