python - 将 self.__class__ 设置为其他东西有多危险?

标签 python python-3.x python-2.x

假设我有一个类,它有许多子类。

我可以实例化这个类。然后我可以将其 __class__ 属性设置为子类之一。我已经有效地将类类型更改为其子类的类型,在一个事件对象上。我可以调用它的方法来调用这些方法的子类版本。

那么,这样做有多危险?看起来很奇怪,但这样做是不是错误?尽管能够在运行时更改类型,但这是应该完全避免的语言特性吗?为什么或为什么不?

(根据回复,我将发布一个更具体的问题,说明我想做什么,以及是否有更好的选择)。

最佳答案

以下是我能想到的导致这种危险的事情的 list ,按从最坏到最不坏的粗略顺序排列:

  • 阅读或调试您的代码的人可能会感到困惑。
  • 您不会获得正确的 __init__ 方法,因此您可能不会正确初始化所有实例变量(甚至根本不会)。
  • 2.x 和 3.x 之间的差异非常显着,移植起来可能会很痛苦。
  • 在类方法、手动编码的描述符、方法解析顺序的 Hook 等方面存在一些极端情况,它们在经典类和新型类之间是不同的(同样,在 2.x 和 3.x 之间)。 x)。
  • 如果您使用 __slots__,则所有类必须具有相同的插槽。 (如果你有兼容但不同的插槽,它可能一开始似乎可以工作,但会做一些可怕的事情......)
  • 新式类中的特殊方法定义可能不会改变。 (事实上​​,这在实践中适用于所有当前的 Python 实现,但它没有记录可以工作,所以……)
  • 如果你使用 __new__,事情就不会按照你天真的预期的方式进行。
  • 如果类有不同的元类,事情会变得更加困惑。

同时,在您认为有必要这样做的许多情况下,还有更好的选择:

  • 使用工厂动态创建适当类的实例,而不是创建基实例,然后将其转换为派生实例。
  • 使用 __new__ 或其他机制来 Hook 构造。
  • 重新设计事物,让您拥有一个具有某些数据驱动行为的类,而不是滥用继承。

作为最后一个最常见的特定情况,只需将所有“变量方法”放入其实例作为“父”的数据成员保存的类中,而不是放入子类中。无需更改 self.__class__ = OtherSubclass,只需执行 self.member = OtherSubclass(self)。如果您真的需要神奇地更改方法,那么自动转发(例如,通过 __getattr__)是一种比动态更改类更常见和 Python 的习惯用法。

关于python - 将 self.__class__ 设置为其他东西有多危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13280680/

相关文章:

python - 如何将列表更改为 HTML 表格? (Python)

python - TensorFlow 如何计算 tf.train.GradientDescentOptimizer 的梯度?

python - 在命令行中 cap.isOpened() 时返回状态

python-3.x - 无法通过 ldap3 Python3 更改用户密码

Python - 返回构造函数参数名称而不实例化

python - 在格式化之前连接两个字符串时,%s 格式先于 + 运算符

python - 正确使用 fftw fft

python - 在 Python 3 游戏上设置固定 FPS

python - 隐式相对导入在 Python 中如何工作?

python - 替换 Pandas 多列中的一系列整数值