2015-04-02 110 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內容才能理解它。

相關問題