2013-06-27 72 views
7

首先,我知道Python中的類的__init__()函數無法返回值,所以很遺憾,此選項不可用。Python __init__返回失敗創建

由於我的代碼的結構,在類的__init__函數內部有數據斷言(並提示用戶提供信息)是有意義的。但是,這意味着對象的創建可能會失敗,並且我希望能夠從中正常恢復。

我想知道繼續這個最好的方法是什麼。我曾考慮將全局布爾值設置爲「有效構造」標誌,但我不想。

任何其他想法(除了重構,所以斷言可能發生在初始化之外,值作爲參數傳遞)?我基本上正在尋找一種方法來成功返回0,並在初始化期間返回-1。 (像大多數C系統調用一樣)

+8

引發異常。 – 2013-06-27 01:07:17

+1

成功時返回0,失敗時返回-1非常不Pythonic。錯誤返回是不好的,因爲它們很容易被忽略,並且處理冗長。最重要的是,使用0和-1作爲布爾值只會增加混淆而沒有任何好處。不要錯過使用Python編寫C代碼。 – abarnert

+0

正如@jsbueno在他的回答中指出的,類實例在__init __()中是_initialized_,而不是創建的,這就是爲什麼它不返回值。你可以添加一個數據成員到你的類來指示它的狀態,然後直接檢查它的值或調用一個方法,它在'__init __()'之後返回它的值,而不是使用全局變量來檢測失敗或拋出異常。被調用以確定是否有任何錯誤(可能是什麼)。 – martineau

回答

11

當任ASSERTIO失敗你也可以拋出一個異常,或者 - 如果你真的不想或不能例外工作,你可以在你的類寫__new__方法 - 在Python,__init__在技術上是一個「初始化器」方法 - 並且它應該填充他的屬性並獲取其對象在其生命週期中需要的一些資源和其他資源 - 然而,Python確實定義了一個真正的構造函數,__new__方法,它在__init__之前被調用 - 並且不像這樣,__new__實際上會返回一個值:新創建的(未初始化的)實例本身。

因此,您可以將檢查置於__new__之內,並簡單地返回無。即失敗 - 否則,將調用的結果返回給超類__new__方法(無法爲純Python中的對象分配實際內存,所以最終你必須調用本機代碼編寫的超類構造函數 - 通常這是你的類層次結構的基礎object.__new__

NB:在Python 2,你必須有object作爲基類你的層次結構 - 否則不會調用__new__,因爲稍後添加到Python對象中的很多功能都不起作用。總之, class MyClass(object):,從來沒有class MyClass: - 除非你在Python3上。

+0

你說'__new__'在'__init__'之前被調用。我只是試過這個,但是當我創建一個類的實例(Py2.7)時不會調用__new__。 –

+0

我找到了。你需要在你的課堂中擴展對象。沒有這個,新的不會被稱爲! –

+0

否。如果省略對象基類,則不會自動調用__new__。去搞清楚! –

0

您是否考慮過引發異常?這是發信號失敗的常用方式。