python元编程:动态创建和修改代码的艺术

30 阅读15分钟

引言:代码即数据,数据即代码

元编程(Metaprogramming)是编写操作代码的代码的能力。Python在这方面提供了丰富的工具,让我们能够在运行时动态地创建、修改和执行代码。这是Python最强大、最神奇的特性之一。

一、动态属性与属性访问控制

1.1 __getattr__ 与 __getattribute__

class DynamicAttributes:
    """动态属性访问示例"""
    
    def __init__(self):
        self._data = {}
        self._access_count = 0
    
    def __getattr__(self, name):
        """当属性不存在时调用"""
        print(f"__getattr__ 被调用: {name}")
        
        # 如果是 "not_found_" 开头的属性,返回一个默认消息
        if name.startswith("not_found_"):
            return f"属性 {name} 不存在,但这是默认值"
        
        # 其他情况抛出 AttributeError
        raise AttributeError(f"'DynamicAttributes' 对象没有属性 '{name}'")
    
    def __getattribute__(self, name):
        """访问任何属性时都会调用(包括存在的属性)"""
        # 避免递归调用
        if name == "_access_count":
            return super().__getattribute__(name)
        
        # 记录访问次数
        self._access_count = getattr(self, "_access_count", 0) + 1
        print(f"属性访问 #{self._access_count}: {name}")
        
        # 使用 super() 避免递归
        return super().__getattribute__(name)
    
    def __setattr__(self, name, value):
        """设置属性时调用"""
        print(f"设置属性: {name} = {value}")
        
        # 特殊处理 _data 属性
        if name == "_data":
            super().__setattr__(name, value)
        else:
            # 其他属性存储在 _data 字典中
            self._data[name] = value
    
    def __delattr__(self, name):
        """删除属性时调用"""
        print(f"删除属性: {name}")
        if name in self._data:
            del self._data[name]
        else:
            super().__delattr__(name)

# 使用示例
obj = DynamicAttributes()
obj.name = "Python"  # 调用 __setattr__
print(obj.name)      # 调用 __getattribute__,然后从 _data 中获取
print(obj.age)       # 调用 __getattribute__,然后 __getattr__(抛出异常)
print(obj.not_found_age)  # 调用 __getattribute__,然后 __getattr__(返回默认值)

# 查看访问统计
print(f"总访问次数: {obj._access_count}")

1.2 描述符(Descriptors)

class ValidatedAttribute:
    """描述符:验证属性值的有效性"""
    
    def __init__(self, validator=None, default=None):
        self.validator = validator
        self.default = default
        self.data = {}
    
    def __get__(self, instance, owner):
        """获取属性值"""
        if instance is None:
            return self
        return self.data.get(id(instance), self.default)
    
    def __set__(self, instance, value):
        """设置属性值,并进行验证"""
        if self.validator and not self.validator(value):
            raise ValueError(f"无效的值: {value}")
        self.data[id(instance)] = value
    
    def __delete__(self, instance):
        """删除属性值"""
        del self.data[id(instance)]

class TypedAttribute(ValidatedAttribute):
    """类型检查描述符"""
    
    def __init__(self, expected_type, default=None):
        validator = lambda x: isinstance(x, expected_type)
        super().__init__(validator, default)
        self.expected_type = expected_type

class RangeAttribute(ValidatedAttribute):
    """范围检查描述符"""
    
    def __init__(self, min_value=None, max_value=None, default=None):
        def validator(value):
            if min_value is not None and value < min_value:
                return False
            if max_value is not None and value > max_value:
                return False
            return True
        
        super().__init__(validator, default)
        self.min_value = min_value
        self.max_value = max_value

class Person:
    """使用描述符的类"""
    
    # 类型检查
    name = TypedAttribute(str, "")
    age = TypedAttribute(int, 0)
    
    # 范围检查
    score = RangeAttribute(min_value=0, max_value=100, default=60)
    
    def __init__(self, name="", age=0, score=60):
        self.name = name
        self.age = age
        self.score = score
    
    def __str__(self):
        return f"Person(name={self.name}, age={self.age}, score={self.score})"

# 测试描述符
p1 = Person()
print(f"默认值: {p1}")

p1.name = "Alice"
p1.age = 25
p1.score = 85
print(f"设置后: {p1}")

try:
    p1.name = 123  # 应该失败:类型错误
except ValueError as e:
    print(f"类型检查: {e}")

try:
    p1.score = 150  # 应该失败:超出范围
except ValueError as e:
    print(f"范围检查: {e}")

# 验证描述符的工作方式
print(f"\n描述符实例: {Person.name}")
print(f"描述符类型: {type(Person.name)}")
print(f"Person类上的name属性: {Person.__dict__['name']}")

# 多个实例共享同一个描述符,但数据隔离
p2 = Person("Bob", 30, 90)
print(f"\nPerson 1: {p1.name}, {p1.age}, {p1.score}")
print(f"Person 2: {p2.name}, {p2.age}, {p2.score}")

1.3 属性(property)的高级用法

class Temperature:
    """使用property实现温度转换"""
    
    def __init__(self, celsius=0):
        self._celsius = celsius
    
    @property
    def celsius(self):
        """摄氏度属性"""
        print("获取摄氏度")
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        """设置摄氏度"""
        print(f"设置摄氏度: {value}")
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        """华氏度属性(只读)"""
        print("计算华氏度")
        return self._celsius * 9/5 + 32
    
    @property
    def kelvin(self):
        """开尔文属性(只读)"""
        print("计算开尔文")
        return self._celsius + 273.15
    
    @kelvin.setter
    def kelvin(self, value):
        """通过开尔文设置温度"""
        print(f"通过开尔文设置温度: {value}")
        self.celsius = value - 273.15

# 使用示例
temp = Temperature(25)
print(f"摄氏度: {temp.celsius}")
print(f"华氏度: {temp.fahrenheit}")
print(f"开尔文: {temp.kelvin}")

temp.celsius = 30
print(f"新华氏度: {temp.fahrenheit}")

temp.kelvin = 300
print(f"新摄氏度: {temp.celsius}")

# property的本质
print(f"\nproperty类型: {type(Temperature.celsius)}")
print(f"property描述符: {Temperature.celsius}")
print(f"fget方法: {Temperature.celsius.fget}")
print(f"fset方法: {Temperature.celsius.fset}")

# 动态创建property
class DynamicPropertyClass:
    """动态添加property"""
    
    def __init__(self):
        self._values = {}
    
    def add_property(self, name, default=None):
        """动态添加一个property"""
        
        # 创建getter和setter
        def getter(self):
            return self._values.get(name, default)
        
        def setter(self, value):
            self._values[name] = value
        
        # 创建property
        prop = property(getter, setter)
        
        # 添加到类中
        setattr(self.__class__, name, prop)

# 测试动态property
obj = DynamicPropertyClass()
obj.add_property("dynamic_attr", "default_value")
obj.add_property("count", 0)

print(f"\n动态属性1: {obj.dynamic_attr}")
obj.dynamic_attr = "new_value"
print(f"动态属性1修改后: {obj.dynamic_attr}")

print(f"动态属性2: {obj.count}")
obj.count = 42
print(f"动态属性2修改后: {obj.count}")

二、元类(Metaclass)

2.1 理解元类:类的类

# 最简单的元类示例
class SimpleMeta(type):
    """简单的元类"""
    
    def __new__(mcs, name, bases, namespace):
        """创建类时调用"""
        print(f"元类 __new__ 被调用:")
        print(f"  元类: {mcs}")
        print(f"  类名: {name}")
        print(f"  基类: {bases}")
        print(f"  命名空间: {namespace.keys()}")
        
        # 修改命名空间:添加一个类属性
        namespace['created_by_meta'] = True
        
        # 调用type的__new__来实际创建类
        return super().__new__(mcs, name, bases, namespace)
    
    def __init__(cls, name, bases, namespace):
        """初始化类时调用"""
        print(f"元类 __init__ 被调用: 初始化类 {cls}")
        super().__init__(name, bases, namespace)
    
    def __call__(cls, *args, **kwargs):
        """创建类的实例时调用"""
        print(f"元类 __call__ 被调用: 创建 {cls} 的实例")
        
        # 可以在创建实例前做一些事情
        print(f"  参数: args={args}, kwargs={kwargs}")
        
        # 调用类的__new__和__init__
        instance = super().__call__(*args, **kwargs)
        
        # 可以在创建实例后做一些事情
        print(f"  创建的实例: {instance}")
        return instance

# 使用元类创建类
class MyClass(metaclass=SimpleMeta):
    """使用SimpleMeta元类的类"""
    
    class_attribute = "类属性"
    
    def __init__(self, value):
        self.value = value
        print(f"MyClass __init__ 被调用: value={value}")
    
    def __str__(self):
        return f"MyClass(value={self.value})"

print("\n" + "="*50)
print("创建类实例:")
print("="*50)

# 创建实例时,元类的__call__会被调用
obj = MyClass("测试值")

print(f"\n类属性: {MyClass.created_by_meta}")
print(f"实例属性: {obj.value}")

# 查看类和元类的关系
print(f"\nMyClass的类型: {type(MyClass)}")
print(f"MyClass的元类: {MyClass.__class__}")
print(f"元类的类型: {type(SimpleMeta)}")
print(f"元类的基类: {SimpleMeta.__bases__}")

2.2 实际应用:自动注册子类

class PluginMeta(type):
    """插件系统元类:自动注册所有子类"""
    
    # 注册表
    _registry = {}
    
    def __new__(mcs, name, bases, namespace):
        """创建类时自动注册"""
        cls = super().__new__(mcs, name, bases, namespace)
        
        # 跳过基类
        if name != "PluginBase":
            plugin_name = namespace.get('plugin_name', name.lower())
            mcs._registry[plugin_name] = cls
            print(f"注册插件: {plugin_name} -> {cls.__name__}")
        
        return cls
    
    @classmethod
    def get_plugin(mcs, name):
        """获取插件类"""
        return mcs._registry.get(name)
    
    @classmethod
    def list_plugins(mcs):
        """列出所有插件"""
        return list(mcs._registry.keys())

class PluginBase(metaclass=PluginMeta):
    """插件基类"""
    
    def run(self):
        raise NotImplementedError

class InputPlugin(PluginBase):
    """输入插件"""
    plugin_name = "input"
    
    def run(self):
        return "处理输入..."

class OutputPlugin(PluginBase):
    """输出插件"""
    plugin_name = "output"
    
    def run(self):
        return "处理输出..."

class TransformPlugin(PluginBase):
    """转换插件"""
    # 如果没有指定plugin_name,使用类名小写
    def run(self):
        return "转换数据..."

class FilterPlugin(PluginBase):
    """过滤插件"""
    plugin_name = "filter"
    
    def run(self):
        return "过滤数据..."

# 使用插件系统
print(f"\n可用插件: {PluginMeta.list_plugins()}")

# 动态创建插件实例
plugin_type = PluginMeta.get_plugin("input")
if plugin_type:
    plugin = plugin_type()
    print(f"运行插件: {plugin.run()}")

# 遍历所有插件
print("\n运行所有插件:")
for plugin_name in PluginMeta.list_plugins():
    plugin_class = PluginMeta.get_plugin(plugin_name)
    plugin = plugin_class()
    print(f"  {plugin_name}: {plugin.run()}")

2.3 动态创建类

def create_class(class_name, base_classes=None, attributes=None):
    """动态创建类"""
    
    if base_classes is None:
        base_classes = (object,)
    
    if attributes is None:
        attributes = {}
    
    # 准备命名空间
    namespace = {
        '__module__': __name__,
        '__qualname__': class_name,
    }
    namespace.update(attributes)
    
    # 使用type创建类
    new_class = type(class_name, base_classes, namespace)
    
    return new_class

# 动态创建类
DynamicPerson = create_class(
    "DynamicPerson",
    attributes={
        "species": "Human",
        "__init__": lambda self, name: setattr(self, "name", name),
        "greet": lambda self: f"Hello, I'm {self.name}",
        "__str__": lambda self: f"DynamicPerson(name={self.name})"
    }
)

# 使用动态创建的类
person = DynamicPerson("Alice")
print(f"动态类实例: {person}")
print(f"调用方法: {person.greet()}")
print(f"类属性: {person.species}")

# 更复杂的动态类创建
def create_data_class(class_name, fields):
    """创建类似dataclass的数据类"""
    
    def __init__(self, *args, **kwargs):
        """动态生成的__init__方法"""
        # 处理位置参数
        for i, field in enumerate(fields):
            if i < len(args):
                setattr(self, field, args[i])
            elif field in kwargs:
                setattr(self, field, kwargs[field])
            else:
                setattr(self, field, None)
    
    def __repr__(self):
        """动态生成的__repr__方法"""
        field_values = ', '.join(
            f"{field}={getattr(self, field)}" 
            for field in fields
        )
        return f"{class_name}({field_values})"
    
    # 创建属性访问方法
    methods = {
        "__init__": __init__,
        "__repr__": __repr__,
    }
    
    # 为每个字段创建property
    for field in fields:
        methods[field] = property(
            lambda self, f=field: getattr(self, f"_get_{f}", lambda: None)(),
            lambda self, value, f=field: getattr(self, f"_set_{f}", lambda v: None)(value)
        )
    
    return type(class_name, (object,), methods)

# 创建数据类
User = create_data_class("User", ["name", "email", "age"])
user = User("Bob", "bob@example.com", 30)
print(f"\n动态数据类: {user}")
print(f"属性访问: name={user.name}, age={user.age}")

三、装饰器工厂与类装饰器

3.1 装饰器工厂

from functools import wraps
from datetime import datetime
import time

def decorator_factory(level="INFO", log_file=None):
    """装饰器工厂:创建带参数的装饰器"""
    
    def decorator(func):
        """实际的装饰器"""
        
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 记录日志
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            log_msg = f"[{level}] {timestamp} - {func.__name__}被调用"
            
            if log_file:
                with open(log_file, "a") as f:
                    f.write(log_msg + "\n")
            else:
                print(log_msg)
            
            # 执行函数
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            
            # 记录执行时间
            duration_msg = f"[{level}] {timestamp} - {func.__name__}执行时间: {end_time-start_time:.4f}秒"
            if log_file:
                with open(log_file, "a") as f:
                    f.write(duration_msg + "\n")
            else:
                print(duration_msg)
            
            return result
        
        return wrapper
    
    return decorator

# 使用装饰器工厂
@decorator_factory(level="DEBUG")
def debug_function():
    """调试函数"""
    time.sleep(0.1)
    return "调试完成"

@decorator_factory(level="ERROR", log_file="error.log")
def error_function():
    """错误函数"""
    time.sleep(0.05)
    raise ValueError("模拟错误")

# 测试
print("测试装饰器工厂:")
result = debug_function()
print(f"结果: {result}")

try:
    error_function()
except ValueError as e:
    print(f"捕获错误: {e}")

# 读取日志文件
with open("error.log", "r") as f:
    print(f"\n错误日志内容:\n{f.read()}")

3.2 类装饰器

class SingletonDecorator:
    """单例类装饰器"""
    
    def __init__(self, cls):
        self.cls = cls
        self._instance = None
    
    def __call__(self, *args, **kwargs):
        """使类成为单例"""
        if self._instance is None:
            self._instance = self.cls(*args, **kwargs)
        return self._instance

@SingletonDecorator
class DatabaseConnection:
    """数据库连接类(单例)"""
    
    def __init__(self, connection_string):
        self.connection_string = connection_string
        print(f"创建数据库连接: {connection_string}")
        self._connected = False
    
    def connect(self):
        self._connected = True
        return f"连接到: {self.connection_string}"

# 测试单例
print("测试单例装饰器:")
db1 = DatabaseConnection("mysql://localhost:3306/mydb")
db2 = DatabaseConnection("mysql://localhost:3306/otherdb")

print(f"db1 is db2: {db1 is db2}")
print(f"db1.connection_string: {db1.connection_string}")
print(f"db2.connection_string: {db2.connection_string}")

class ValidateAttributesDecorator:
    """验证类属性的装饰器"""
    
    def __init__(self, cls):
        self.cls = cls
    
    def __call__(self, *args, **kwargs):
        """创建实例时验证属性"""
        instance = self.cls(*args, **kwargs)
        self._validate_attributes(instance)
        return instance
    
    def _validate_attributes(self, instance):
        """验证所有以'_validate_'开头的方法"""
        for attr_name in dir(instance):
            if attr_name.startswith("_validate_"):
                validator = getattr(instance, attr_name)
                if callable(validator):
                    field_name = attr_name[10:]  # 去掉'_validate_'
                    value = getattr(instance, field_name, None)
                    if not validator(value):
                        raise ValueError(f"属性 {field_name} 验证失败: {value}")

@ValidateAttributesDecorator
class User:
    """用户类,属性会被自动验证"""
    
    def __init__(self, name, age, email):
        self.name = name
        self.age = age
        self.email = email
    
    def _validate_name(self, value):
        """验证姓名"""
        return isinstance(value, str) and len(value) >= 2
    
    def _validate_age(self, value):
        """验证年龄"""
        return isinstance(value, int) and 0 <= value <= 150
    
    def _validate_email(self, value):
        """验证邮箱(简化)"""
        return isinstance(value, str) and "@" in value

print("\n测试属性验证装饰器:")
try:
    user1 = User("Alice", 25, "alice@example.com")
    print(f"用户1创建成功: {user1.name}")
except ValueError as e:
    print(f"用户1创建失败: {e}")

try:
    user2 = User("A", 200, "invalid-email")
    print(f"用户2创建成功: {user2.name}")
except ValueError as e:
    print(f"用户2创建失败: {e}")

四、代码生成与动态导入

4.1 使用execeval

import ast
import math

def safe_exec(code_string, globals_dict=None, locals_dict=None):
    """安全执行代码,限制可访问的模块"""
    
    if globals_dict is None:
        globals_dict = {}
    
    # 安全的全局命名空间
    safe_globals = {
        '__builtins__': {
            'print': print,
            'len': len,
            'range': range,
            'list': list,
            'dict': dict,
            'int': int,
            'str': str,
            'float': float,
            'bool': bool,
            'sum': sum,
            'max': max,
            'min': min,
            'abs': abs,
            'round': round,
            'math': math,  # 允许使用math模块
        }
    }
    safe_globals.update(globals_dict)
    
    # 执行代码
    try:
        # 先编译检查语法
        compiled = compile(code_string, '<string>', 'exec')
        
        # 在限制的环境中执行
        exec(compiled, safe_globals, locals_dict)
        
        # 返回结果
        return safe_globals.get('result', None)
    except Exception as e:
        return f"执行错误: {e}"

def dynamic_calculator(expression, variables=None):
    """动态计算器"""
    
    if variables is None:
        variables = {}
    
    # 构建计算代码
    code = f"""
result = {expression}
"""
    
    # 执行计算
    return safe_exec(code, variables)

# 使用示例
print("动态计算器示例:")
variables = {'x': 10, 'y': 20, 'z': 30}

# 简单计算
result = dynamic_calculator("x + y * z", variables)
print(f"x + y * z = {result}")

# 使用数学函数
result = dynamic_calculator("math.sin(math.pi / 2)", variables)
print(f"sin(π/2) = {result}")

# 复杂表达式
result = dynamic_calculator("sum([x, y, z]) / len([x, y, z])", variables)
print(f"平均值 = {result}")

def generate_class_dynamically(class_name, methods_dict):
    """动态生成类"""
    
    # 构建类定义代码
    imports = """
from datetime import datetime
import json
"""
    
    # 生成方法代码
    methods_code = []
    for method_name, method_body in methods_dict.items():
        method_code = f"""
    def {method_name}(self, *args, **kwargs):
        {method_body}
"""
        methods_code.append(method_code)
    
    # 完整的类代码
    class_code = f"""
{imports}

class {class_name}:
    def __init__(self, name):
        self.name = name
        self.created_at = datetime.now()
    
    def __str__(self):
        return f"{class_name}(name={{self.name}})"
    
    def to_json(self):
        return json.dumps({{
            'name': self.name,
            'created_at': self.created_at.isoformat()
        }})
    
    {''.join(methods_code)}
"""
    
    # 执行代码生成类
    namespace = {}
    exec(class_code, namespace)
    
    return namespace[class_name]

# 动态生成类
DynamicGeneratedClass = generate_class_dynamically(
    "DynamicService",
    {
        "greet": '''return f"Hello, {self.name}!"''',
        "process_data": '''return sum(args) if args else 0''',
        "validate_input": '''return kwargs.get("valid", False)'''
    }
)

# 使用动态生成的类
service = DynamicGeneratedClass("TestService")
print(f"\n动态生成的类实例: {service}")
print(f"调用方法1: {service.greet()}")
print(f"调用方法2: {service.process_data(1, 2, 3, 4, 5)}")
print(f"调用方法3: {service.validate_input(valid=True)}")
print(f"JSON表示: {service.to_json()}")

4.2 AST(抽象语法树)操作

import ast
import inspect

class CodeTransformer(ast.NodeTransformer):
    """代码转换器:修改AST"""
    
    def visit_FunctionDef(self, node):
        """访问函数定义节点"""
        
        # 重命名函数(添加前缀)
        node.name = f"transformed_{node.name}"
        
        # 添加装饰器
        decorator = ast.Name(id='staticmethod', ctx=ast.Load())
        node.decorator_list.append(decorator)
        
        # 添加文档字符串
        if not ast.get_docstring(node):
            docstring = ast.Expr(value=ast.Constant(value="动态添加的文档字符串"))
            node.body.insert(0, docstring)
        
        # 继续处理子节点
        self.generic_visit(node)
        return node
    
    def visit_Call(self, node):
        """访问函数调用节点"""
        
        # 将所有的print改为大写PRINT
        if isinstance(node.func, ast.Name) and node.func.id == 'print':
            node.func.id = 'PRINT'
        
        # 继续处理子节点
        self.generic_visit(node)
        return node

def transform_code(source_code):
    """转换源代码"""
    
    # 解析为AST
    tree = ast.parse(source_code)
    
    # 应用转换器
    transformer = CodeTransformer()
    transformed_tree = transformer.visit(tree)
    
    # 添加缺失的行号信息
    ast.fix_missing_locations(transformed_tree)
    
    # 编译并执行
    code_object = compile(transformed_tree, '<transformed>', 'exec')
    
    # 创建新的命名空间
    namespace = {'PRINT': print}  # 提供PRINT函数
    
    # 执行转换后的代码
    exec(code_object, namespace)
    
    return namespace

# 要转换的源代码
original_code = """
def hello(name):
    print(f"Hello, {name}!")

def calculate(a, b):
    result = a + b
    print(f"结果: {result}")
    return result
"""

print("AST转换示例:")
print("原始代码:")
print(original_code)

print("\n转换后的代码执行结果:")
namespace = transform_code(original_code)

# 调用转换后的函数
try:
    # 函数名被修改了
    namespace['transformed_hello']("World")
    result = namespace['transformed_calculate'](10, 20)
    print(f"计算结果: {result}")
except KeyError as e:
    print(f"找不到函数: {e}")

def analyze_function(func):
    """分析函数的AST"""
    
    # 获取源代码
    source = inspect.getsource(func)
    
    # 解析为AST
    tree = ast.parse(source)
    
    # 分析AST
    analyzer = ASTAnalyzer()
    analyzer.visit(tree)
    
    return analyzer.report()

class ASTAnalyzer(ast.NodeVisitor):
    """AST分析器"""
    
    def __init__(self):
        self.functions = []
        self.calls = []
        self.variables = set()
        self.imports = []
    
    def visit_FunctionDef(self, node):
        """分析函数定义"""
        self.functions.append({
            'name': node.name,
            'args': [arg.arg for arg in node.args.args],
            'lineno': node.lineno,
            'docstring': ast.get_docstring(node)
        })
        self.generic_visit(node)
    
    def visit_Call(self, node):
        """分析函数调用"""
        if isinstance(node.func, ast.Name):
            self.calls.append(node.func.id)
        self.generic_visit(node)
    
    def visit_Name(self, node):
        """分析变量名"""
        if isinstance(node.ctx, ast.Store):  # 赋值
            self.variables.add(node.id)
        self.generic_visit(node)
    
    def visit_Import(self, node):
        """分析导入"""
        for alias in node.names:
            self.imports.append(alias.name)
        self.generic_visit(node)
    
    def visit_ImportFrom(self, node):
        """分析from...import"""
        for alias in node.names:
            self.imports.append(f"{node.module}.{alias.name}")
        self.generic_visit(node)
    
    def report(self):
        """生成分析报告"""
        return {
            'functions': self.functions,
            'calls': list(set(self.calls)),
            'variables': list(self.variables),
            'imports': self.imports
        }

# 分析示例函数
def example_function(x, y):
    """示例函数"""
    import math
    result = x + y
    z = math.sqrt(result)
    print(f"计算结果: {z}")
    return z

print("\nAST分析示例:")
analysis = analyze_function(example_function)
print(f"函数分析: {analysis['functions']}")
print(f"函数调用: {analysis['calls']}")
print(f"变量: {analysis['variables']}")
print(f"导入: {analysis['imports']}")

五、实际应用:ORM框架的实现

class Field:
    """ORM字段基类"""
    
    def __init__(self, field_type, primary_key=False, nullable=True, default=None):
        self.field_type = field_type
        self.primary_key = primary_key
        self.nullable = nullable
        self.default = default
    
    def __str__(self):
        return f"Field(type={self.field_type.__name__})"

class ModelMeta(type):
    """Model的元类"""
    
    def __new__(mcs, name, bases, namespace):
        # 跳过基类
        if name == "Model":
            return super().__new__(mcs, name, bases, namespace)
        
        # 收集字段
        fields = {}
        for key, value in list(namespace.items()):
            if isinstance(value, Field):
                fields[key] = value
                # 从命名空间中移除字段,避免成为类属性
                del namespace[key]
        
        # 创建类
        cls = super().__new__(mcs, name, bases, namespace)
        
        # 设置元数据
        cls._fields = fields
        cls._table_name = namespace.get('__table__', name.lower())
        
        # 生成__init__方法
        mcs._create_init_method(cls, fields)
        
        # 生成SQL创建语句
        cls._create_table_sql = mcs._generate_create_table_sql(cls)
        
        return cls
    
    @staticmethod
    def _create_init_method(cls, fields):
        """动态生成__init__方法"""
        
        def __init__(self, **kwargs):
            self._data = {}
            
            # 设置字段值
            for field_name, field in fields.items():
                value = kwargs.get(field_name)
                
                if value is None and field.default is not None:
                    value = field.default() if callable(field.default) else field.default
                
                if value is None and not field.nullable and not field.primary_key:
                    raise ValueError(f"字段 {field_name} 不能为None")
                
                setattr(self, field_name, value)
        
        cls.__init__ = __init__
    
    @staticmethod
    def _generate_create_table_sql(cls):
        """生成创建表的SQL语句"""
        
        columns = []
        for field_name, field in cls._fields.items():
            column_def = f"{field_name} {field.field_type}"
            
            if field.primary_key:
                column_def += " PRIMARY KEY"
            
            if not field.nullable:
                column_def += " NOT NULL"
            
            if field.default is not None:
                default_value = field.default() if callable(field.default) else field.default
                column_def += f" DEFAULT {repr(default_value)}"
            
            columns.append(column_def)
        
        sql = f"CREATE TABLE IF NOT EXISTS {cls._table_name} (\n"
        sql += ",\n".join(f"    {col}" for col in columns)
        sql += "\n);"
        
        return sql

class Model(metaclass=ModelMeta):
    """ORM模型基类"""
    
    def __init__(self, **kwargs):
        pass
    
    def save(self):
        """保存到数据库(模拟)"""
        print(f"保存 {self.__class__.__name__} 到数据库")
        print(f"数据: {self._data}")
    
    @classmethod
    def create_table(cls):
        """创建表(模拟)"""
        print(f"创建表 {cls._table_name}:")
        print(cls._create_table_sql)
    
    def __str__(self):
        fields_str = ", ".join(
            f"{name}={getattr(self, name)}" 
            for name in self._fields.keys()
        )
        return f"{self.__class__.__name__}({fields_str})"

# 定义具体的模型类
class User(Model):
    """用户模型"""
    __table__ = "users"
    
    id = Field(int, primary_key=True)
    username = Field(str, nullable=False)
    email = Field(str, nullable=False)
    age = Field(int, nullable=True, default=18)
    created_at = Field(str, default=lambda: "2024-01-01")

class Product(Model):
    """产品模型"""
    __table__ = "products"
    
    id = Field(int, primary_key=True)
    name = Field(str, nullable=False)
    price = Field(float, nullable=False)
    stock = Field(int, default=0)

# 使用ORM
print("ORM框架示例:")

# 查看生成的SQL
print("\n1. 创建表的SQL:")
User.create_table()
Product.create_table()

# 创建实例
print("\n2. 创建模型实例:")
user1 = User(id=1, username="alice", email="alice@example.com")
print(f"用户1: {user1}")

user2 = User(id=2, username="bob", email="bob@example.com", age=25)
print(f"用户2: {user2}")

product1 = Product(id=101, name="Python Book", price=59.99, stock=100)
print(f"产品1: {product1}")

# 保存到数据库
print("\n3. 保存到数据库:")
user1.save()
product1.save()

# 验证元数据
print("\n4. 模型元数据:")
print(f"User表名: {User._table_name}")
print(f"User字段: {list(User._fields.keys())}")
print(f"User字段类型: {{name: type(field.field_type).__name__ for name, field in User._fields.items()}}")

# 尝试无效数据
print("\n5. 验证数据约束:")
try:
    invalid_user = User(id=3)  # 缺少必填字段
except ValueError as e:
    print(f"验证失败: {e}")

总结

Python元编程提供了强大的工具来操作代码本身:

  1. 动态属性:通过 __getattr____getattribute__、描述符等控制属性访问
  2. 元类:控制类的创建过程,实现自动注册、验证等高级功能
  3. 装饰器工厂:创建可配置的装饰器,增强函数或类的功能
  4. 动态代码生成:使用 execeval、AST 操作在运行时生成和修改代码

元编程的关键原则:

  • 谨慎使用:元编程增加了复杂性,只在必要时使用
  • 保持可读性:确保生成的代码可读可维护
  • 安全性第一:动态执行代码时要特别注意安全性
  • 了解原理:深入理解 Python 的对象模型和查找机制