添加类方法后如何更新类的实例?



我发现自己陷入了困境,我开发了一个类,然后我创建了这个类的实例。这些类通常会执行数据和统计操作,这需要很长时间,有时需要 20 分钟。

我将继续开发我的类,并向其添加其他方法。现在,如何使用新方法更新以前的类实例,而无需重新初始化类的旧实例,在这种情况下需要 20 分钟?

这里有一个XY问题。 你真正的困难似乎是"__init__需要 20 分钟才能完成"。

有几种办法可以摆脱这种困境。

  1. 花几分钟时间计算一个新实例,然后安排将其快速序列化到磁盘。如果反序列化时间不到二十分钟,你就赢了!
  2. 使用间接寻址级别,因此具有如此多有趣行为的对象是轻量级的,消耗很少的内存。让它包含指向 RDBMS ID、S3 存储桶、URL 或文件名的指针。
  3. 将昂贵的对象存储在全局或等效对象中,例如使用@lru_cache,并让您更新/重新加载的类以这种方式找到它。使用importlib.reload().
  4. 与序列化类似,提供便宜的 .copy() 并利用继承。
  5. 猴子补丁。

这是利用继承的一种方法 (复制不是必需的,但会使其更干净):

class FooBase:
...
# global variable for expensive computation
foo = FooBase()
class FooFeature(FooBase):
def __init__(self, foo):
...
def some_new_feature(self):
...
foo = FooFeature(foo.copy())  # This happens quickly.

这是猴子补丁的一种方法:

class Foo:
...
foo = Foo()
FooOriginal = Foo
# Now you edit in a brand new Foo feature and reload the class definition:
def new_feature(self):
...
FooOriginal.new_feature = Foo.new_feature

猴子打补丁时, 请注意,foo包含对FooOriginal包含的同一类对象的引用。 重新加载后,Foo变成一个全新的对象, 使用一种附加方法。 最后的猴子补丁作业 使该方法可用于FooOriginal, 因此可供foo

.

最新更新