当前位置: 首页 > 面试题库 >

将self .__ class__设置为其他东西有多危险?

翟新
2023-03-14
问题内容

假设我有一个类,其中包含许多子类。

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

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

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


问题答案:

这是我能想到的导致危险的列表,从最坏到最坏的顺序排列:

  • 这可能会使阅读或调试您的代码的人感到困惑。
  • 您将没有正确的__init__方法,因此您可能不会正确初始化(甚至根本不)初始化所有实例变量。
  • 2.x和3.x之间的差异非常明显,以至于移植起来可能很痛苦。
  • 在某些情况下,类方法,手工编码的描述符,方法解析顺序的钩子等等,在经典类和新型类之间(以及在2.x和3.x之间),它们是不同的。
  • 如果使用__slots__,则所有类都必须具有相同的插槽。(并且,如果您具有兼容但不同的插槽,则乍一看似乎可以正常工作,但是却做得很糟糕……)
  • 新型类中的特殊方法定义可能不会更改。(实际上,这将在实践中与所有当前的Python实现一起使用,但是没有 文档记录 ,因此……)
  • 如果使用__new__,事情将不会像您天真的预期那样工作。
  • 如果这些类具有不同的元类,那么事情将变得更加混乱。

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

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

作为最后一个最常见的特定情况,只需将所有“变量方法”放入其html" target="_blank">实例作为“父”数据成员保存的类中,而不是子类中即可。不要改变self.__class__ = OtherSubclass,而要做self.member = OtherSubclass(self)。如果您确实需要进行神奇更改的方法,那么自动转发(例如via
__getattr__)比动态更改类更为常见和Python化。



 类似资料:
  • Item Command Files generated Component: ng g component [name] component, HTML, CSS, test spec files Directive: ng g directive [name] component, test spec files Pipe: ng g pipe [name] component, test s

  • 问题内容: 我已经在这里阅读了很多帖子并在网上冲浪,但是也许我没有问正确的问题。我知道在集群可用之前,Redis目前是主/从服务器。但是,我想知道是否有人可以告诉我如何在逻辑上配置Redis以满足我的需要(或者如果它不是正确的工具)。 场景: 我们在美国的两端有2个站点。我们希望客户能够在每个站点上大量书写。然后,我们希望每个客户端也能够在其站点上执行读取。但是,我们希望在小于50ms的时间内从姐

  • 问题内容: 我有一个选择查询,我试图在字符串中搜索多个模式 返回零结果 然而 返回结果并 返回结果 是否可以将我所有的结果合并为一个查询?如果一个字符串匹配两者,它将如何处理? 问题答案: 如果可以的话,这会很好,但是您不能在SQL中使用该语法。 试试这个: 注意使用括号!您需要在表达式周围使用它们。 如果没有括号,它将被解析为,不会为您带来预期的结果。

  • 我在一个流畅的API上调用一个库方法,它需要一个字符串的变量。当我调用它时,我总是传递至少三个字符串,然后根据情况再传递几个。 可以有一个最终的静态数组或其他东西来捕获总是传递的三个字符串?

  • 因为BouncyCastle jar是经过签名的,在maven assembly plugin中使用带有依赖项的jar将破坏这些签名,我想知道是否有可能创建这种输出: 我的代码和每个依赖项都在一个胖罐子中,但不包括BC罐子 库/子文件夹中的BC jar 我设法排除BC jar在我的脂肪罐使用一个程序集文件看起来像: 现在,我如何告诉maven assembly插件将BC jar作为独立jar放在l

  • 问题内容: 与在元素上设置元素的innerHTML与在元素上设置危险地设置InnerHTML属性有什么“幕后”区别?假设为简单起见,我正在对事物进行适当的消毒。 例: 与 我做的事情比上面的示例复杂一些,但总体思路是相同的 问题答案: 是,有一点不同! 使用vs 的直接效果是相同的-DOM节点将使用注入的HTML更新。 但是 ,在使用它时,让React 在幕后知道该组件内部的HTML并不是它关心的