python 函数—文档、类型注释和内省

Python 文档、类型注释和内省

目录

  1. 引言
  2. 函数文档
    • docstring 的使用
    • help() 函数
  3. 类型注释
    • 基本类型注释
    • 复杂类型注释
  4. 内省技术
    • 基本内省方法
    • inspect 模块的高级内省
  5. 综合示例
  6. 建议

引言

Python 提供了丰富的文档和内省机制,使开发者能够编写自解释的代码并在运行时检查对象属性。本教程详细介绍了函数文档、类型注释和内省技术。

函数文档

docstring 的使用

Python 使用三引号字符串('''""")作为文档字符串(docstring),用于描述模块、类、方法或函数的功能。

def calculate_area(radius):
    """计算圆的面积。

    Args:
        radius (float): 圆的半径

    Returns:
        float: 圆的面积
    """
    import math
    return math.pi * radius ** 2

help() 函数

help() 是 Python 的内置函数,用于查看对象的文档。它会显示从 docstring 中提取的信息。

# 模块级别的 help
import math
help(math)  # 显示整个 math 模块的文档

# 函数级别的 help
help(math.sin)  # 显示 sin 函数的文档

# 自定义函数的 help
def greet(name):
    """向指定的人打招呼。
    
    Args:
        name: 要问候的人的名字
    
    Returns:
        包含问候语的字符串
    """
    return f"你好,{name}!"

help(greet)  # 显示 greet 函数的文档

类型注释

基本类型注释

Python 3.5+ 支持类型注释,帮助开发者和工具理解代码中变量和函数的预期类型。

def add_numbers(a: int, b: int) -> int:
    """将两个整数相加。
    
    Args:
        a: 第一个整数
        b: 第二个整数
        
    Returns:
        两个整数的和
    """
    return a + b

# 带有默认值的类型注释
def greet_user(name: str = "用户") -> str:
    return f"你好,{name}!"

复杂类型注释

对于更复杂的类型,可以使用 typing 模块。

from typing import List, Dict, Tuple, Optional, Union, Any

def process_data(items: List[int]) -> Dict[str, Any]:
    """处理整数列表并返回结果字典。"""
    return {
        "count": len(items),
        "sum": sum(items),
        "average": sum(items) / len(items) if items else 0
    }

def get_user_info(user_id: int) -> Optional[Dict[str, Union[str, int]]]:
    """获取用户信息,如果用户不存在则返回 None。"""
    # 示例实现
    users = {1: {"name": "张三", "age": 30}}
    return users.get(user_id)

# 函数类型注释
def apply_operation(x: int, operation: Callable[[int], int]) -> int:
    """对整数应用指定的操作。"""
    return operation(x)

内省技术

基本内省方法

内省允许程序在运行时检查对象的类型和属性。

def basic_introspection_demo():
    """演示基本的内省技术。"""
    # 检查对象类型
    number = 42
    text = "Hello"
    print(f"number 的类型: {type(number)}")
    print(f"text 的类型: {type(text)}")
    
    # 列出对象的属性和方法
    print(f"\ntext 的方法和属性:")
    print(dir(text)[:5])  # 只显示前5个
    
    # 检查对象是否具有特定属性
    print(f"\n'upper' 是否是 text 的属性: {'upper' in dir(text)}")
    
    # 访问文档字符串
    print(f"\n当前函数的文档字符串: {basic_introspection_demo.__doc__}")

inspect 模块的高级内省

inspect 模块提供了更强大的内省功能。

import inspect

def advanced_introspection_demo():
    """演示使用 inspect 模块的高级内省技术。"""
    
    def sample_function(a: int, b: str = "默认值") -> bool:
        """一个带有类型注释的示例函数。"""
        return True
    
    # 获取函数签名
    sig = inspect.signature(sample_function)
    print(f"函数签名: {sig}")
    
    # 获取参数信息
    print("\n参数详情:")
    for name, param in sig.parameters.items():
        print(f"  {name}: {param.annotation}, 默认值={param.default}")
    
    # 获取返回类型注释
    print(f"返回类型: {sig.return_annotation}")
    
    # 获取源代码
    print(f"\n函数源代码:\n{inspect.getsource(sample_function)}")
    
    # 获取定义位置
    print(f"\n函数定义位置: {inspect.getfile(sample_function)}, 行 {inspect.getsourcelines(sample_function)[1]}")

综合示例

下面是一个综合示例,演示了如何将文档、类型注释和内省结合使用:

from typing import List, Dict, Any, Optional
import inspect

class DataAnalyzer:
    """数据分析工具类。
    
    该类演示了如何结合使用文档字符串、类型注释和内省技术。
    
    Attributes:
        name: 分析器名称
        data_source: 数据来源
        results: 分析结果缓存
    """
    
    def __init__(self, name: str, data_source: str):
        """初始化数据分析器。
        
        Args:
            name: 分析器名称
            data_source: 数据来源标识
        """
        self.name = name
        self.data_source = data_source
        self.results: Dict[str, Any] = {}
        
    def analyze(self, dataset: List[float]) -> Dict[str, float]:
        """分析数据集并返回统计结果。
        
        Args:
            dataset: 要分析的数值列表
            
        Returns:
            包含统计结果的字典
        
        Raises:
            ValueError: 如果数据集为空
        """
        if not dataset:
            raise ValueError("数据集不能为空")
            
        result = {
            "count": len(dataset),
            "mean": sum(dataset) / len(dataset),
            "min": min(dataset),
            "max": max(dataset)
        }
        
        # 计算标准差
        mean = result["mean"]
        variance = sum((x - mean) ** 2 for x in dataset) / len(dataset)
        result["std_dev"] = variance ** 0.5
        
        # 保存结果到缓存
        self.results["latest"] = result
        return result
        
    def get_metadata(self) -> Dict[str, str]:
        """返回分析器元数据。
        
        Returns:
            包含元数据的字典
        """
        return {
            "name": self.name,
            "data_source": self.data_source,
            "has_results": "yes" if self.results else "no"
        }


def inspect_class(cls) -> None:
    """检查并显示类的详细信息。
    
    Args:
        cls: 要检查的类
    """
    print(f"类名: {cls.__name__}")
    print(f"文档: {cls.__doc__}")
    print("\n方法:")
    
    for name, method in inspect.getmembers(cls, predicate=inspect.isfunction):
        if not name.startswith('_') or name == '__init__':
            sig = inspect.signature(method)
            print(f"\n  {name}{sig}")
            if method.__doc__:
                print(f"  文档: {method.__doc__.strip()}")
            print("  参数:")
            for param_name, param in sig.parameters.items():
                if param_name != 'self':
                    print(f"    - {param_name}: {param.annotation}")
            print(f"  返回类型: {sig.return_annotation}")


if __name__ == "__main__":
    # 演示类的内省
    print("===== 检查 DataAnalyzer 类 =====\n")
    inspect_class(DataAnalyzer)
    
    # 使用该类
    print("\n\n===== 使用 DataAnalyzer 类 =====\n")
    analyzer = DataAnalyzer("温度分析器", "weather_station_1")
    result = analyzer.analyze([21.5, 22.0, 23.1, 20.8, 22.5])
    print(f"分析结果: {result}")
    print(f"元数据: {analyzer.get_metadata()}")
    
    # 使用内置 help 函数
    print("\n\n===== 内置 help 输出 =====\n")
    help(DataAnalyzer.analyze)

建议

  1. 始终编写文档字符串:为所有模块、类和函数提供清晰的文档字符串。
  2. 使用一致的文档格式:遵循 Google、NumPy 或 reStructuredText 等文档风格。
  3. 添加类型注释:特别是对于公共 API 和复杂函数。
  4. 结合使用类型注释和文档字符串:类型注释提供类型信息,文档字符串提供语义解释。
  5. 利用内省进行调试和测试:特别是在处理未知对象时。
  6. 安装静态类型检查工具:使用 mypy 或 PyCharm 等工具来检查类型兼容性。

你可能感兴趣的:(python,python,开发语言)