Python的__new__有哪些使用场景?

14

我了解__new__的作用(以及它与__init__的区别),因此我不感兴趣的是定义,而是关心何时以及如何使用__new__

文档说明如下:

通常情况下,您不需要覆盖__new__,除非您正在子类化像strintunicodetuple这样的不可变类型。

但我想不到其他用例来使用__new__,也不知道如何正确使用它(例如在子类化不可变类型时为什么需要它)。

那么,何时、为什么以及如何需要使用__new__呢?

我感兴趣的是使用情况,而不是它的作用(我知道它的作用)。


2
@McFarlane:我知道这一点,我感兴趣的是你需要使用__new__的情况(不仅仅是“子类化不可变类型”的短语)。这不是重复内容。 - JohnDoDo
1
@关闭投票者 这不是重复的问题。所引用的问题询问为什么__init__始终在__new__之后调用(事实并非如此)。此问题询问__new__的实际用例。这个问题的答案不是那个问题的答案。 - Lauritz V. Thaulow
又来一个关闭投票者?请仔细阅读文本。它说:“这个问题涵盖了与此主题早期问题完全相同的内容。它的答案可能会与另一个相同的问题合并”(我强调)。但事实并非如此。合并后的问题中的答案将显得不协调! - Lauritz V. Thaulow
你会在Python中的元类是什么?中找到非常好的用例。 - Piotr Dobrogost
@Donal Fellows,您能否考虑撤销您的关闭投票? - Lauritz V. Thaulow
显示剩余8条评论
2个回答

14

就我个人而言,我用它来:

  • 创建单例模式(虽然有方法可以在不使用__new__的情况下实现单例)
  • 动态扩展外部模块中的类而无需实际编辑源代码
  • 在元类中自定义类(尽管我认为也可以使用__call__
  • 扩展datetime.datetime类(它是不可变的),以便在未使用参数实例化时返回当前时间,并且在使用单个字符串参数调用strptime的结果。

如果您要更改用于构造不可变对象的参数,例如在datetime示例中所需的内容,或者如果您不想调用父类的__new__而是返回以其他方式创建的实例甚至是完全不同类型的实例,则需要使用__new__,当您到达__init__时,任何更改对象的方式都太晚了,因此需要在__new__中操作。


你能分享一下你是如何完成第四点的吗?扩展datetime.datetime类...... - mahes

2
一个潜在的用例可能是一个“工厂类”,根据实现返回不同类的实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接