# 反射(Reflection)是指在程序运行时检查、访问和修改其自身状态和行为的能力。Python 作为一种高度动态的语言,天然支持强大的反射机制。 # 2.核心价值 # 动态性:在运行时操作对象 # 灵活性:根据条件动态调用方法 # 通用性:编写可重用的通用代码 # 内省:检查对象的结构和能力 # 核心函数 # 函数 描述 返回值 # hasattr(obj, name) 检查对象是否有指定属性 布尔值 # getattr(obj, name[, default]) 获取对象属性值 属性值或默认值 # setattr(obj, name, value) 设置对象属性值 None # delattr(obj, name) 删除对象属性 None # dir(obj) 获取对象所有属性和方法 列表 # 基本用法 class Example: def __init__(self): self.value = 42 example = Example() # 检查属性是否存在 print(hasattr(example, "value")) # True # 获取某个属性值 print(getattr(example, "value")) # 42 # 设置新属性 setattr(example, "new_attr", 100) print(getattr(example, "new_attr")) # 100 # 删除属性 delattr(example, "new_attr") print("new_attr" in dir(example)) # False print(dir(example)) # 安全属性访问 class Config: def __init__(self): self.host = "localhost" self.port = "8080" config = Config() timeout = getattr(config, "timeout", 300) # 如果不存在设置默认值 print(timeout) # 返回默认值 print("timeout" in dir(config)) # False 不会设置上去 # 内省函数 # 4.1.类型检查函数 # 函数 描述 示例 # type(obj) 返回对象类型 type(123) → # isinstance(obj, class) 检查对象是否为指定类型 isinstance(123, int) → True # issubclass(cls, class) 检查类继承关系 issubclass(Bar, Foo) → True # 对象信息函数 # 函数 描述 示例 # dir(obj) 获取对象所有属性和方法 dir(obj) → ['attr1', 'method1', ...] # vars(obj) 获取对象的属性字典 vars(obj) → {'attr1': 'value1'} # obj.__dict__ 对象的属性字典 obj.__dict__ → {'attr1': 'value1'} # 示例 class Foo: def __init__(self): self.attr1 = "hello" class Bar(Foo): def method1(self): return "world" foo = Foo() bar = Bar() # 类型 print(type(foo)) # print(isinstance(bar, Foo)) # True print(issubclass(Bar, Foo)) # True # 对象信息 print(hasattr(foo, "attr1")) # True print(getattr(foo, "attr1")) # hello print(vars(foo)) # {'attr1': 'hello'} print(vars(bar)) # {'attr1': 'hello'} print( dir(foo) ) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'attr1'] def show_object_members(obj): print(f"对象类型: {type(obj)}") for attr in dir(obj): if attr.startswith("_"): continue value = getattr(obj, attr) if callable(value): print(f"[方法] {attr}()") else: print(f"[属性] {attr} = {value}") # 使用示例 show_object_members(123) # 类级别反射是指直接作用于类本身的反射操作,可以: # 动态获取和修改类属性(包括类变量) # 调用类方法和静态方法 # 检查类中的方法和属性是否存在 # 动态给类添加属性或方法 class DatabaseModel: table_name = "users" connection_string = "sqlite:///database.bd" def __init__(self, id, name): self.id = id self.name = name # @classmethod 装饰器可以将方法包装成类方法,类方法直接通过类来调用,不需要创建实例 @classmethod def get_table_info(cls): return f"表名:{cls.table_name},连接{cls.connection_string}" # @staticmethod 将方法变为静态方法。静态方法既可以通过类来调用,也可以通过实例来调用,但他们并不会接受任何饮食的第一参数(既不接受类对象,也不接受实例对象) @staticmethod def validata_data(data): return isinstance(data, dict) def save(self): return f"保存{self.name}到数据库中" # 类级别的反射操作 print(getattr(DatabaseModel, "table_name")) print(getattr(DatabaseModel, "connection_string")) # 动态修改属性 setattr(DatabaseModel, "table_name", "customers") print(getattr(DatabaseModel, "table_name")) # customers # 调用类的方法 class_method = getattr(DatabaseModel, "get_table_info") print(class_method()) # 调用静态方法 static_method = getattr(DatabaseModel, "validata_data") print(static_method({"key": "val"})) # True # 检查类成员 print(hasattr(DatabaseModel, "table_name")) # True print(hasattr(DatabaseModel, "connection_string")) # True print(hasattr(DatabaseModel, "get_table_info")) # True # 模块级别反射 # 7.1.概念 # 模块级反射是指在运行时动态地检查、导入、操作模块及其内容的能力。它可以帮助我们开发出高度可配置、插件化、支持热加载的系统。 # 7.2.常用函数 # 函数 描述 示例 # importlib.import_module(name) 按名称动态导入模块 importlib.import_module("math") # getattr(module, name[, default]) 动态获取模块中的函数、类、变量 getattr(math, "sqrt") # hasattr(module, name) 判断模块是否有某个属性 hasattr(math, "pow") # dir(module) 获取模块内定义的名称列表 dir(math) # importlib.reload(module) 重新加载已加载的模块 importlib.reload(math) # 基本示例 import importlib from typing import Any # 动态导入模块 module_name = "math" math_mod = importlib.import_module(module_name) print( math_mod ) # print(getattr(math_mod, "sqrt")(16)) # 4.0 # 检查是否存在某属性 if hasattr(math_mod, "pow"): print(math_mod.pow(2, 8)) # 256.0 # 应用场景 # 配置系统 class ConfigManager: def __init__(self, config_dict=None): self._config = config_dict or {} self._defaultConfig = { "debug": False, "host": "localhost", "port": 8080, "timeout": 30, } def __getattr__(self, name): if name in self._config: return self._config.get(name) elif name in self._defaultConfig: return self._defaultConfig.get(name) else: raise ArithmeticError(f"配置选项不存在{name}") def set_config(self, **kwargs): for key, val in kwargs.items(): self._config[key] = val def show_config(self): all_config = {**self._defaultConfig, **self._config} for key, val in all_config.items(): source = "默认" if key in self._defaultConfig else "自定义" print(f"{key}:{val}[{source}]") config = ConfigManager() print(f"Host: {config.host}") # localhost print(f"Port: {config.port}") # 8080 print(f"Debug: {config.debug}") # False config.set_config(host="127.0.0.1", port=9000, new_setting="custom") print("\n所有配置:") config.show_config() requests = [ ("GET", "/users"), ("GET", "/users/123"), ("POST", "/users", {"name": "Alice", "email": "alice@example.com"}), ("PUT", "/users/123", {"name": "Alice Smith"}), ("DELETE", "/users/123"), ] # *args 会返回一个list for method, path, *args in requests: params = args[0] if args else {}