Files
2026-05-06 11:21:42 +08:00

254 lines
7.9 KiB
Python

# 反射(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) → <class 'int'>
# 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)) # <class '__main__.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
) # <module 'math' from '/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload/math.cpython-312-darwin.so'>
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 {}