imm*_*imm 28 python python-2.x
假设我有一个类,它有一个数字子类.
我可以实例化这个类.然后我可以将其__class__属性设置为其中一个子类.我已经在类活动对象上有效地将类类型更改为其子类的类型.我可以调用它上面的方法来调用子类的那些方法的版本.
这样做有多危险?这看起来很奇怪,但做这样的事情是不对的吗?尽管能够在运行时更改类型,这是否应该完全避免使用该语言的功能?为什么或者为什么不?
(根据回复,我会发布一个更具体的问题,关于我想做什么,以及是否有更好的选择).
aba*_*ert 22
这里列出了我能想到的一些事情,这些事情使得这种事情变得危险,从最坏到最不好的粗略顺序:
__init__方法,因此您可能无法正确初始化所有实例变量(甚至根本没有).__slots__,所有类必须具有相同的插槽.(如果你有兼容但不同的插槽,它可能看起来首先工作,但做了可怕的事......)__new__,事情将不会像你天真的预期那样发挥作用.同时,在许多情况下,您认为这是必要的,有更好的选择:
__new__或其他机制钩住建筑.作为最后一个最常见的特定情况,只需将所有"变量方法"放入其实例作为"父"的数据成员而不是子类的类中.而不是改变self.__class__ = OtherSubclass,只是做self.member = OtherSubclass(self).如果你真的需要神奇地改变方法,那么自动转发(例如,通过__getattr__)是一种比在飞行中改变类更常见和更加疯狂的习语.
hyn*_*cer 15
__class__如果您有很长时间运行应用程序并且需要在不丢失数据的情况下用同一类的较新版本替换某个对象的旧版本,则分配该属性非常有用,例如,在reload(mymodule)没有重新加载未更改的模块之后.其他示例是如果您实现持久性 - 类似于pickle.load.
不鼓励使用所有其他用法,特别是如果您可以在启动应用程序之前编写完整的代码.
在任意类上,这极不可能起作用,而且即使起作用也非常脆弱。这与从一个类的方法中提取底层函数对象,并在不是原始类实例的对象上调用它们基本上是一样的。这是否有效取决于内部实现细节,并且是一种非常紧密的耦合形式。
也就是说,在专门设计用于这种方式的__class__一组类中更改对象可能是完全没问题的。我很早就知道你可以这样做,但我还没有找到这种技术的用途,同时想到更好的解决方案。因此,如果您认为自己有一个用例,那就去做吧。只需在您的评论/文档中明确发生了什么即可。特别是,这意味着所涉及的所有类的实现必须尊重它们的所有不变量/假设/等,而不是能够孤立地考虑每个类,因此您需要确保任何从事以下任何一项工作的人所涉及的代码知道这一点!