2015-04-02 107 views
1

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

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

这是该类型的__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内容才能理解它。

相关问题