2012-10-23 35 views
4

當我寫它,它似乎是超現實的,我認爲我確實遇到了這個問題。正確使用`isinstance(OBJ,類)的'

我有一個對象列表。這些對象中的每一個都是我編寫的Individual類的實例。

因此,傳統觀念認爲,isinstance(myObj, Individual)應返回True。但是,情況並非如此。所以我想,有我在節目中的錯誤,並打印type(myObj),這讓我吃驚的印刷instancemyObj.__class__給我Individual

>>> type(pop[0]) 
<type 'instance'> 
>>> isinstance(pop[0], Individual) # with all the proper imports 
False 
>>> pop[0].__class__ 
Genetic.individual.Individual 

我很難過!是什麼賦予了?

編輯:我個人類

class Individual: 
    ID = count() 
    def __init__(self, chromosomes): 
     self.chromosomes = chromosomes[:] # managed as a list as order is used to identify chromosomal functions (i.e. chromosome i encodes functionality f) 
     self.id = self.ID.next() 

    # other methods 

回答

12

這個錯誤表示Individual類不知何故創造了兩次。您使用Instance的一個版本創建了pop[0],並正在檢查另一個版本。雖然它們幾乎完全相同,但Python不知道,並且isinstance失敗。要驗證這一點,請檢查pop[0].__class__ is Individual的計算結果是否爲false。

通常類並沒有生成兩次(除非你用reload),因爲模塊是進口的只有一次,所有的類對象有效保持單身。但是,使用軟件包和相對導入可能會導致導致模塊導入兩次的陷阱。當一個腳本(從python bla開始,而不是從另一個帶有import bla的模塊導入)包含相對導入時,會發生這種情況。運行腳本時,Python不知道它的進口參考Genetic包,所以它處理的進口爲絕對,打造頂級individual模塊都以其自身individual.Individual類。另一個其他模塊正確導入Genetic程序包,最終導入Genetic.individual,這導致創建了doppelganger,Genetic.individual.Individual

要解決該問題,請確保您的腳本僅使用絕對導入,例如import Genetic.individual,即使像import individual這樣的相對導入看起來很好。如果您想節省打字時間,請使用import Genetic.individual as individual。另請注意,儘管您使用舊式課程,isinstance仍然可以使用,因爲它早於新式課程。話雖如此,切換到新風格的課程將是非常明智的。

+0

'pop [0] .__ class__ is Genetic.individual.Individual' evaluate to'True'。 – inspectorG4dget

+1

但是'pop [0] .__ class__ is Individual'在您的交互式Python會話中評估爲'isinstance(pop [0],Individual)'評估爲False? (我的答案應該更加精確。) – user4815162342

+0

是的,那個評估結果爲'False' – inspectorG4dget

1

您需要使用從

class ClassName(object): 
    pass 

從你的例子繼承的新樣式類,您使用的是繼承老式類

class Classname: 
    pass 

編輯:@ user4815162342 sai d,

>>> type(pop[0]) 
<type 'instance'> 

通過使用舊式類造成的,但這不是與isinstance你的問題的原因。您應該確保您不要在多個地方創建該類,或者如果您這樣做,請使用不同的名稱。多次導入不應該成爲問題。

+2

或使用Python 3 – XORcist

+0

你可以發佈一個解釋,爲什麼這可以修復錯誤?另外,我的代碼在昨天工作,所以我也對其他可能的解釋感興趣 – inspectorG4dget

+0

因爲繼承與舊式類無法相同。對於新式類,'isinstance'實質上檢查'obj .__ class__',然後遞歸地在'obj .__ class __.__ bases__'中找到每個超類。對於舊式課程,這種行爲不能保證。如果我們能看到你的定義,我們可能能夠解釋爲什麼不在你的情況下。 – bossylobster