为什么构造函数不是第二次调用?

时间:2015-04-02 20:28:04

标签: python-2.7 inheritance copy-constructor

为什么第二次没有调用构造函数?

from datetime import datetime

class Time(datetime):
    def __init__(self, *args):
        print 5, args
        try:
            d = args[0]
            print 8, d
            datetime.__init__(self,
                d.year, d.month, t.day, t.hour, t.minute, t.second)
        except Exception:
            print 12, args
            datetime.__init__(self, args)

if __name__ == '__main__':
    t = Time(1965, 1, 10)
    print 17, t
    u = Time(t)
    print 19, u

使用python 2.7.2,这是输出:

bash-4.1$ python tmp.py
5 (1965, 1, 10)
8 1965
12 (1965, 1, 10)
17 1965-01-10 00:00:00
Traceback (most recent call last):
  File "tmp.py", line 18, in <module>
    u = Time(t)
TypeError: an integer is required

我希望看到:

5 Time(1965, 1, 10)

如果不是构造函数,则调用什么函数?

1 个答案:

答案 0 :(得分:1)

这是类型的__new__方法。

__init__不是创建对象时首先发生的事情。首先,调用类型的__new__方法来实际生成对象,然后调用__init__来初始化它。对于可变类型,__new__通常不会做太多,但对于datetime这样的不可变类型,__new__通常会创建预初始化的对象,否则__init__将不得不改变对象以初始化它。

如果您想继承datetime,则必须实施__new__以及__init__

def __new__(cls, *args):
    print 5, args
    try:
        d = args[0]
        print 8, d
        return datetime.__new__(cls,
            d.year, d.month, t.day, t.hour, t.minute, t.second)
    except Exception:
        print 12, args
        return datetime.__new__(cls, args)

如果您想查看datetime __new__所做的事情,可以在Modules/datetimemodule.c中看到它。但是你必须知道C并且知道或者查找一堆Python C-api来理解它。

相关问题