1. 反射是什么? #

2. 四个核心函数 #

函数 作用
hasattr(obj, "name") 是否有该属性
getattr(obj, "name"[, default]) 取值;不存在可返回默认值
setattr(obj, "name", value) 动态设属性(慎用)
dir(obj) 列出名称,调试、探索用
# 定义 Settings 类
class Settings:
    def __init__(self):
        self.host = "localhost"
        self.port = 8080

cfg = Settings()

# 获取 host 属性
print(getattr(cfg, "host"))
# 无 timeout 时返回默认值 30
print(getattr(cfg, "timeout", 30))
# 判断是否有 debug 属性
print(hasattr(cfg, "debug"))

# 动态增加 debug 属性
setattr(cfg, "debug", True)
print(cfg.debug)

3. 动态调用方法 #

# 定义 UserService 类
class UserService:
    def list_users(self):
        return [{"name": "Alice"}, {"name": "Bob"}]
    def create_user(self, name: str):
        return {"name": name}

svc = UserService()
# 要调用的方法名(实际项目应对 action 做白名单校验)
action = "list_users"

# 先判断方法是否存在
if hasattr(svc, action):
    fn = getattr(svc, action)
    # 确认是可调用对象后再执行
    if callable(fn):
        result = fn()
        print(result)

4. 按名字段访问 #

# 定义一个示例 User 类并创建 user 实例,保证代码可运行
class User:
    def __init__(self, name, email, status):
        self.name = name
        self.email = email
        self.status = status

user = User("Alice", "alice@example.com", "active")

# 遍历允许的字段名(白名单!)
result = {}
for field in ("name", "email", "status"):
    # 按字段名动态取值,不存在时返回 None
    value = getattr(user, field, None)
    result[field] = value
# 补全代码:例如可以将结果打印输出或者做其他操作
print(result)

5. 模块动态导入 #

# 导入 importlib 模块
import importlib

# 按字符串路径动态导入模块
module = importlib.import_module("myapp.models.User")
# 从模块中获取类
User = getattr(module, "User")
user = User()
print(user)

6. 内省 #

# 打印 user 对象的类型
print(type(user))          # <class '__main__.User'>
# 判断 user 是否是 User 类型的实例,返回布尔值
print(isinstance(user, User))  # True
# 列出 user 对象的所有属性和方法名
print(dir(user))           # ['__class__', ... 'email', 'name', 'status']
# 返回 user 对象的属性字典
print(vars(user))          # {'name': 'Alice', 'email': ..., 'status': ...}

7. __getattr__ #

# 定义一个配置代理类,主要用于当访问不存在的属性时从字典查找
class Config:
    # 初始化方法,接收一个字典参数 data
    def __init__(self, data: dict):
        # 保存传入的字典为实例变量 _data
        self._data = data

    # 当访问实例不存在的属性时,会触发该方法
    def __getattr__(self, name: str):
        # 如果属性名在 _data 字典中
        if name in self._data:
            # 返回对应字典的值
            return self._data[name]
        # 如果属性名不在字典中,抛出 AttributeError 异常
        raise AttributeError(name)

# 创建 Config 实例,传入一个有 'host' 和 'port' 键的字典
config = Config({'host': 'localhost', 'port': 3306})
# 访问 config.host 属性,实际返回 _data['host'] 即 localhost
print(config.host)  # 输出: localhost
# 访问 config.port 属性,实际返回 _data['port'] 即 3306
print(config.port)  # 输出: 3306
# 使用 try-except 结构,尝试访问不存在的 user 属性
try:
    # 访问不存在的属性 config.user,会触发 __getattr__ 并抛出异常
    print(config.user)  # 触发 AttributeError
# 捕获 AttributeError 异常,将异常信息打印出来
except AttributeError as e:
    print(f"AttributeError: {e}")

8. 项目开发要点 #

9. 总结 #

API 项目场景
getattr(..., default) 缺省配置、可选属性
hasattr 判断是否有某能力再调用
getattr + callable 命令/插件分发(少用)
importlib.import_module 按名加载模块
dir / vars 调试