【问题标题】:how to override class, or undeclare class or redeclare a Class in python?如何在python中覆盖类,取消声明类或重新声明一个类?
【发布时间】:2012-03-22 10:12:58
【问题描述】:

是否有可能在 python 中覆盖类、取消声明类或重新声明一个类?

【问题讨论】:

  • 请提供您想要做的代码示例。

标签: python class


【解决方案1】:

是的,只需再次声明:

class Foo(object): x = 1

class Foo(object): x = 2

上述代码不会引发任何错误,名称Foo 将引用声明的第二个类。但是请注意,如果有任何东西引用它,则第一个声明所声明的类仍然存在,例如实例或派生类。

这意味着当你声明一个同名的新类时,现有的实例不会改变类,现有的子类也不会神奇地从新类继承。

可能最简单的处理子类的方法是重新声明它们,因此它们继承自“更新的”基类。另一种方法是弄乱他们的__bases__ 属性,尽管我不能告诉你这是否会产生意想不到的结果(几乎可以肯定,在某些极端情况下这是行不通的)。

对于现有实例,可以使用新类重新分配其__class__ 属性。这确实存在两个问题 - 首先您必须找到它们(请参阅此问题:Printing all instances of a class),其次,存储在实例 __dict____slots__ 属性中的项目在这些实例中仍然存在。如果这不是您的新类定义应该发生的事情,您将必须编写适当的代码来处理它作为转换的一部分。

总而言之,除非在非常简单的情况下,否则不太可能值得。如果您需要运行系统的完整正常运行时间,您最好使用基于复制的方法来实现代码更改。

更新:如果这是您知道自己将要做的事情,另一种解决方案是使用策略模式。

【讨论】:

  • 但是第一类的实例呢?第一类的子类?你如何更新它们?
  • 您取消声明或重新定义的类的实例不受影响。通过重新定义或取消声明,您只会影响 className 的全球已知标识符。类的编译代码仍然存在,直到没有实例不再使用它。您不能更改现有实例的代码。
  • @Alfe 抱歉,您没有阅读我的回答吗?这些信息从一开始就在我的回答中。
  • @Marcin 我刚刚在上面的评论中回答了 agf 的问题。
  • @Alfe 再一次,我的回答已经包含了这些信息。
【解决方案2】:

像往常一样使用del className 取消声明一个类。

【讨论】:

  • 嘿 Alfe,您的回答没有提到您取消声明或重新定义的类的实例不受影响。通过重新定义或取消声明,您只会影响 className 的全球已知标识符。类的编译代码仍然存在,直到没有实例不再使用它。您不能更改现有实例的代码。
猜你喜欢
  • 2013-06-03
  • 2014-08-19
  • 1970-01-01
  • 2017-08-22
  • 2014-03-23
  • 1970-01-01
  • 2020-08-08
  • 2011-07-05
  • 2023-04-03
相关资源
最近更新 更多