Python的反射和自省
已于 2025年10月12日 10:01 修改
访问次数:0
Python 的反射(Reflection)与自省(Introspection) —— 这两个概念在 Python 里非常重要,尤其在框架设计、动态加载模块、ORM(如 Django)、单元测试等场景中经常用到。
🧠 一、基本概念
✅ 自省(Introspection)
自省是指程序在运行时能够获取自身的信息,比如:
- 一个对象属于哪个类;
- 对象有哪些属性或方法;
- 模块里定义了哪些变量、函数、类;
- 函数的参数有哪些。
👉 简单来说,自省是“让程序认识自己”。
✅ 反射(Reflection)
反射是指在运行时动态地操作对象——比如根据字符串名去访问、修改或调用对象的属性和方法。
换句话说,自省是“了解自己”,而反射是“根据这种了解去做事情”。
🧩 二、常用自省与反射函数
| 函数 | 作用 |
|---|---|
type(obj) | 查看对象的类型 |
id(obj) | 查看对象的内存地址 |
dir(obj) | 列出对象的所有属性和方法(包括内置的) |
hasattr(obj, name) | 判断对象是否有某个属性或方法 |
getattr(obj, name, default) | 获取属性或方法(可提供默认值) |
setattr(obj, name, value) | 动态设置属性 |
delattr(obj, name) | 动态删除属性 |
isinstance(obj, cls) | 判断对象是否某个类的实例 |
issubclass(sub, super) | 判断一个类是否另一个类的子类 |
callable(obj) | 判断对象是否可调用 |
inspect 模块 | 提供更详细的自省功能(查看源代码、参数等) |
🔍 三、反射示例
class Student:
def __init__(self, name):
self.name = name
def say_hello(self):
print(f"Hi, I'm {self.name}")
stu = Student("Alice")
# ---- 自省 ----
print(type(stu)) # <class '__main__.Student'>
print(dir(stu)) # 查看 stu 拥有哪些属性与方法
print(hasattr(stu, 'name')) # True
# ---- 反射 ----
attr = getattr(stu, 'name') # 动态获取属性值
print(attr) # Alice
method = getattr(stu, 'say_hello') # 动态获取方法
method() # 调用方法:Hi, I'm Alice
setattr(stu, 'age', 20) # 动态添加属性
print(stu.age) # 20
delattr(stu, 'age') # 动态删除属性
💡 典型应用场景:
- 动态加载模块或类(如 importlib.import_module())
- 根据配置文件调用不同函数
- Django ORM 根据模型类反射数据库字段
🔧 四、inspect 模块:更强的自省工具
Python 的标准库 inspect 提供了更强的自省功能。
import inspect
def demo_func(a, b, c=1):
return a + b + c
print(inspect.signature(demo_func)) # (a, b, c=1)
print(inspect.getsource(demo_func)) # 查看源码
print(inspect.getmodule(demo_func)) # 获取函数所在模块
print(inspect.isfunction(demo_func)) # True
print(inspect.getmembers(demo_func)) # 获取所有成员信息
🧩 五、自省 vs 反射 对比总结
| 对比项 | 自省 (Introspection) | 反射 (Reflection) |
|---|---|---|
| 含义 | 了解对象信息 | 动态操作对象 |
| 典型函数 | type(), dir(), isinstance() | getattr(), setattr(), delattr() |
| 作用 | “知道有什么” | “用这些做事情” |
| 应用场景 | 调试、分析程序结构 | 框架设计、动态调用 |
🧱 六、实际应用例子(模拟路由调用)
比如在一个 Web 框架中,可以用反射根据 URL 动态调用控制器方法:
class UserView:
def login(self):
print("User login")
def logout(self):
print("User logout")
def run_action(view_class, action_name):
view = view_class()
if hasattr(view, action_name):
func = getattr(view, action_name)
func() # 动态执行方法
else:
print("Action not found")
run_action(UserView, "login") # 输出:User login
run_action(UserView, "logout") # 输出:User logout
✅ 总结一句话:
自省是了解自己,反射是根据了解去动态操作。 Python 通过这些机制让代码更加“动态”和“灵活”,是其元编程能力的重要体现
评论(0)