You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Jupyter中通过已有实例Monkey Patching类的方法与属性

需求:无需重新初始化耗时实例,自动更新已有类实例的方法与属性

在Jupyter做项目原型开发时,希望不用手动修改类或重新初始化耗时的实例,就能自动给已有类实例添加/删除方法与属性。举个例子:

class A(object):
    def __init__(self):
        # 耗时的初始化操作

    def keep_this_fxn(self):
        return 'hi'

a = A()

# 现在想把A升级成A_new
class A_new(object):
    def __init__(self, v):
        # 同样耗时的初始化操作
        self._new_prop = v

    def keep_this_fxn(self):
        return 'hi'

    @property
    def new_prop(self):
        return self._new_prop

    def new_fxn(self):
        return 'hey'

希望不用手动执行A.new_fxn = A_new.new_fxn或者重新初始化实例,就能自动完成这类更新。比如实现一个update_instance函数,达到以下效果:

def update_instance(a, new_instance):
    # 实现逻辑在这里?

# 调用时不能像原初始化那样慢!
a = update_instance(a, A_new(5))

>>> type(a)  # 最好保持原类名
<A>
>>> a.keep_this_fxn()  # 保留原方法功能
'hi'
>>> a.new_fxn()  # 新增方法可用
'hey'
>>> a.new_prop  # 新增属性可用
5

之前查过相关帖子,但都没覆盖这种场景(尤其是新增属性和参数的情况)。

当前尝试的代码:

def update_class_instance(instance, NewClass, new_method_list):
    OrigClass = type(instance).__mro__[0]
    
    for method in new_method_list:
        setattr(OrigClass, method, getattr(NewClass, method))    

但存在两个问题:

  • 必须手动指定new_method_list,希望能自动识别新增的方法
  • 不知道如何处理新增的属性和参数

解决方案

要实现这个需求,我们可以从实例属性拷贝和类动态补丁两方面入手:

1. 自动识别新旧类的差异

通过对比原类与新类的成员,自动找出新增/修改的方法、特性(@property),同时从新实例中提取新增的实例属性,无需手动指定列表。

2. 实现update_instance函数

def update_instance(original_instance, new_instance):
    orig_cls = type(original_instance)
    new_cls = type(new_instance)

    # 处理类层面的方法和特性
    orig_members = {k: v for k, v in orig_cls.__dict__.items() if not k.startswith('__')}
    new_members = {k: v for k, v in new_cls.__dict__.items() if not k.startswith('__')}

    # 新增/更新类方法与特性
    for name, member in new_members.items():
        if name not in orig_members or member != orig_members[name]:
            setattr(orig_cls, name, member)

    # 处理实例层面的属性(从新实例拷贝新增属性)
    new_instance_attrs = {k: v for k, v in new_instance.__dict__.items() if k not in orig_cls.__dict__}
    for attr_name, attr_value in new_instance_attrs.items():
        setattr(original_instance, attr_name, attr_value)

    # 可选:删除原类中被移除的成员
    # for name in orig_members:
    #     if name not in new_members:
    #         delattr(orig_cls, name)

    return original_instance

3. 使用示例

# 原实例初始化
a = A()

# 创建新实例(仅执行一次耗时初始化)
new_a = A_new(5)

# 更新原实例
a = update_instance(a, new_a)

# 验证效果
print(type(a))  # <class '__main__.A'>
print(a.keep_this_fxn())  # 'hi'
print(a.new_fxn())  # 'hey'
print(a.new_prop)  # 5

关键说明

  • 类层面的修改是全局的:所有A类的实例都会被更新,适合原型开发场景
  • 实例属性直接从新实例拷贝,避免重复执行耗时初始化
  • 自动识别新增的方法和特性,无需手动指定列表
  • 如果仅需更新单个实例而非全局类,可修改为直接给实例绑定方法(但特性只能绑定到类)

内容的提问来源于stack exchange,提问作者irene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:35:20