如何重置 Python 类为其原始状态

99 阅读2分钟

在 Python 中,有时我们会动态地向类添加一些属性,但之后又希望将类恢复到其原始状态,即删除这些动态添加的属性。然而,直接删除类属性可能会导致异常,因为类属性是类的一部分,不能直接修改。

huake_00257_.jpg 2. 解决方案 为了解决这个问题,有几种方法可以实现:

  • 使用装饰器: 通过装饰器我们可以实现类的属性重置功能,在类定义中使用 @resetable 装饰器,然后在需要恢复类属性时,使用 reset() 函数即可。这种方法可以保证类的属性即使被修改,也能恢复到其原始状态。

def resetable(cls): cls.resetable_cache = cls.dict.copy() return cls

def reset(cls): cache = cls.resetable_cache # raises AttributeError on class without decorator for key in [key for key in cls.dict if key not in cache]: delattr(cls, key) for key, value in cache.items(): # reset the items to original values try: setattr(cls, key, value) except AttributeError: pass

@resetable # use resetable on a class that you want to do this with class Foo(object): pass

Foo.x = 1 print Foo.x reset(Foo) o = Foo() print o.x # raises AttributeError as expected ```

  • 显式记录和恢复原始状态: 这种方法比较简单,但需要明确地记录类的原始状态,并在需要恢复时显式地将其恢复。这种方法可以保证类的属性在被修改后,能够恢复到其原始状态。

class Foo(object): pass

try: original_value = getattr(Foo, 'x') originally_existed = True except AttributeError: originally_existed = False

Foo.x = 1

if originally_existed: Foo.x = original_value else: del Foo.x

o = Foo() # o should not have any of the previously added attributes print o.x # Should raise exception ```

  • 使用 inspect 模块: 这种方法使用 inspect 模块来获取类的原始成员列表,然后删除所有不在原始列表中的成员。这种方法可以保证类的属性在被修改后,能够恢复到其原始状态。

import inspect orig_members = [] for name, ref in inspect.getmembers(o): orig_members.append(name) ...

Now, when you need to restore back to original for name, ref in inspect.getmembers(o): if name in orig_members: pass else: #delete ref here ```

  • 使用类生成器: 这种方法比较简单,只需要定义一个类生成器函数,每次需要重新创建类时,都使用这个类生成器函数生成一个新的类。这种方法可以保证类的属性每次都是从头开始,不会受到之前修改的影响。

def foo_maker(): class Foo(object): pass return Foo Foo = foo_maker() Foo.x = 1 Foo = foo_maker() # Foo is now clean again o = Foo() # Does not have any of the previously added attributes print o.x # Raises exception ```

注意: 在使用这些方法时,需要注意以下几点:

  • 这些方法只能应用于类属性,不能应用于实例属性。
  • 这些方法只能恢复类的属性,不能恢复类的行为。
  • 这些方法可能会破坏类的继承关系,因此在使用时需要谨慎。