为什么__new__不带参数时__init__不被调用

7 投票
2 回答
2156 浏览
提问于 2025-04-16 22:40

我正在尝试创建一个对象,这个对象的属性保存在数据库里。所以,我不想调用 __init__ 方法。这个想法似乎和 Guido 对 __new__ 的初衷 是一致的。我不明白为什么 __init__ 没有被调用。

举个例子,下面这段代码返回了一个 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 文档,当 __new__ “返回一个 cls 的实例”时,应该会调用 __init__

那么,为什么即使 __new__ 返回了一个类的实例,__init__ 还是没有被调用呢?

2 个回答

10

因为你直接调用了 __new__,绕过了通常的对象创建方式。__init____new__ 之后的逻辑是在 type.__call__ 里面(在 CPython 中可以查看 typeobject.c 文件里的 type_call 函数),所以只有当你使用 User(...) 这样的方式时,这个逻辑才会发生。

13

构造函数User())的作用是依次调用分配器User.__new__())和初始化器User.__init__())。但是,由于构造函数从来没有被调用,所以初始化器也就没有被执行。

撰写回答