【问题标题】:Why does __init__ not get called if __new__ called with no args如果在没有参数的情况下调用 __new__ 为什么不调用 __init__
【发布时间】:2011-08-01 19:28:42
【问题描述】:

我正在尝试创建(不完全恢复)其属性保存在数据库中的对象。因此,我不想打电话给__init__。这种愿望似乎与Guido's intended use for __new__ 一致。我不明白为什么 __init__ 没有被调用。

以下面的sn-p为例,它返回一个User类的实例,而不调用__init__

class User(object):
    def __init__(self, arg1, arg2):
        raise Exception

user = User.__new__(User)

print user
<project.models.User object at 0x9e2dfac>

这正是我想要的行为。但是,我的问题是我不明白为什么?

根据python docs__init__应该在__new__“返回一个cls的实例”时被调用。

那么为什么__init__ 甚至没有被调用,即使__new__ 返回一个类实例?

【问题讨论】:

  • 请发布实际运行的代码。你的意思是def __init__
  • 我遇到了同样的事情并且知道 python 不这样做。然而,文档清楚地说“如果 __new__() 返回一个 cls 的实例,那么新实例的 __init__() 方法将像 __init__(self[, ...]) 一样被调用”。这是一个文档错误还是我误解了它?
  • @UsAaR33 你误解了它。调用SomeClass(args) 将(通常)执行instance = SomeClass.__new__(SomeClass, args),然后如果instanceSomeClass 的一个实例,则调用instance.__init__(args)。文档是在该序列的上下文中讨论__new__,而不是在任何时候调用它,因为直接调用__new__ 比首先需要定义它更罕见。

标签: python


【解决方案1】:

构造函数 (User()) 负责调用allocator (User.__new__()) 和initializer (User.__init__())反过来。由于从不调用构造函数,因此从不调用初始化程序。

【讨论】:

    【解决方案2】:

    因为你绕过了通常的构造机制,直接调用__new____init__-after-__new__ 逻辑在 type.__call__ 中(在 CPython 中请参阅 typeobject.ctype_call 函数),因此它仅在您执行 User(...) 时才会发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-15
      • 2022-01-25
      • 2018-06-23
      • 1970-01-01
      • 2015-08-24
      相关资源
      最近更新 更多