Logo
Section 1 / 11

检查与扩展 Python 运行时(orientation)

学习使用 getattr、dir 和 inspect 模块查询实时的 Python 运行时,以分析对象、动态获取源代码并推理程序状态。

导入

检查与扩展 Python 运行时(orientation)

学习使用 getattr、dir 和 inspect 模块查询实时的 Python 运行时,以分析对象、动态获取源代码并推理程序状态。

1import math 2 3# 我们定义一个全局变量和一个函数 4user_limit = 100 5 6def calculate_usage(): 7 return 42 8 9# 我们可以直接检查全局命名空间 10namespace = globals() 11 12print(f"'user_limit' 是否在 globals 中?{'user_limit' in namespace}") 13print(f"user_limit 的值: {namespace['user_limit']}") 14 15# 我们甚至可以找到已导入的模块 16print(f"math 模块是否已加载?{'math' in namespace}") 17 18# 我们可以在全局作用域中通过类型查找对象 19print("\n全局作用域中的函数:") 20# 我们使用 list() 创建 items 的静态副本,以避免在迭代过程中字典大小变化导致的运行时错误 21for name, value in list(namespace.items()): 22 if callable(value) and name == "calculate_usage": 23 print(f"- 找到函数: {name}()")
1class UserConfig: 2 theme = "Dark Mode" 3 notifications = True 4 version = 3.1 5 6config = UserConfig() 7 8# 模拟从用户或文件读取设置名称 9setting_name = "theme" 10 11# 静态访问(需要在编写代码时知道 'theme' 这个名称) 12print(f"静态访问: {config.theme}") 13 14# 动态访问(使用字符串变量) 15value = getattr(config, setting_name) 16print(f"动态访问: {value}") 17 18# 安全处理缺失的属性 19# 若不提供默认值,这将引发 AttributeError 20unknown = getattr(config, "layout", "Default Layout") 21print(f"缺失属性的回退值: {unknown}")
1import inspect 2 3class DataProcessor: 4 def process_text(self, text): 5 return text.strip() 6 7 def process_number(self, num): 8 return num * 2 9 10 def _internal_helper(self): 11 pass 12 13# 我们希望动态查找所有 'process' 方法 14processor = DataProcessor() 15 16print("DataProcessor 中的方法:") 17# getmembers 返回 (name, value) 元组 18for name, func in inspect.getmembers(processor, predicate=inspect.ismethod): 19 if name.startswith("process_"): 20 print(f"找到处理器: {name}")
1import inspect 2 3def connect_db(host: str, port: int = 5432) -> bool: 4 """连接到数据库。""" 5 return True 6 7# 1. 检查函数签名 8sig = inspect.signature(connect_db) 9print(f"函数参数: {sig.parameters}") 10 11# 访问特定参数的详细信息 12port_param = sig.parameters["port"] 13print(f"端口默认值: {port_param.default}") 14print(f"端口注解: {port_param.annotation}") 15 16# 2. 获取源代码 17# 注意:此方法仅适用于在源文件中定义的函数(不适用于交互式 shell) 18try: 19 source_lines = inspect.getsource(connect_db) 20 print(f"\n源代码:\n{source_lines}") 21except OSError: 22 print("无法获取源代码。")
1def confidential_handler(): 2 return "Sensitive Data" 3 4def public_handler(): 5 return "Public Data" 6 7# 我们为函数添加自定义元数据 8confidential_handler.is_admin_only = True 9public_handler.is_admin_only = False 10 11# 我们可以模拟一个权限检查系统 12def execute_handler(handler, user_is_admin): 13 # 安全地检查函数的自定义属性 14 requires_admin = getattr(handler, "is_admin_only", False) 15 16 if requires_admin and not user_is_admin: 17 print(f"访问被拒绝: {handler.__name__}") 18 else: 19 print(f"结果: {handler()}") 20 21print("用户(普通):") 22execute_handler(public_handler, user_is_admin=False) 23execute_handler(confidential_handler, user_is_admin=False)

高级函数与装饰器

动态属性与类修改