2012-02-17 73 views
3

下面是我正在試圖解決的編碼問題......我有一個基類,讓我們說Animal,它有兩個子類,Dog和Cat。我的類動物有一個方法,make_baby(),狗和貓都會繼承。我無法解決的技巧是,我希望返回值是調用該函數但具有不同屬性值的子類的新實例,即Dog.make_baby()應該返回一個新的Dog和Cat.make_baby() )將返回一個新的貓。Python類:在基類的方法中創建變量子類

我以前試過返回「type(self)()」,但這不好,因爲type()返回一個類型對象,而不是類。

以下是完整的示例代碼:

Class Animal(): 
    def __init__(self, color): 
    self.color = color 
    def make_baby(): 
    new_color = rand_color # a randomly chosen color 
    return #??? new class of the same type that called the method 

Class Dog(Animal): 
    def pet(): 
    print '*pant*' 

Class Cat(Animal): 
    def pet(): 
    print 'purrr' 

所以我想避免寫狗和貓一make_baby()方法,因爲這個想法是,該方法是完全除外返回相同類。我還想避免一堆if語句,因爲我想爲Animal創建任意大量的子類。

回答

10

您寫道:

這是沒有好,因爲類型()返回一個類型的對象,而不是一類。

A類型一個類,如果您使用的是新式類。如果你使用的是Python 3,那麼你已經設置好了;所有Python 3類都是「新式」。如果您使用的是Python 2.x,則可以從object(或其他來自對象的其他內容(如任何內置Python類型))派生類。

但是你真正想要的是一個類方法,在這裏你可以獲得對自動傳入的類的引用。

class Animal(object): 

    def __init__(self, color): 
    self.color = color 

    @classmethod 
    def make_baby(cls): 
    return cls(rand_color) # randomly-chosen color 

可以調用它的類(例如Animal.make_baby()Dog.make_baby())或上的一個實例;無論哪種方式,該方法仍然接收該類作爲第一個參數。

+0

謝謝!這真是讓我煩惱,因爲我真的有我的真正的代碼使用type(self)(...),但是然後莫名其妙地停止工作。我意識到這是因爲我的基類最初是列表的一個子類,我決定這沒有意義,所以我刪除了它,並且沒有父類。我已經添加了對象作爲父類,它再次運行!我打算使用您提出的@classmethod建議,這聽起來像一個靈活的想法。再次感謝。 – ampron 2012-02-17 21:09:09

+2

如果需要實例,則類方法將不適用,例如如果涉及遺傳學。雖然在這種情況下,通過動態打字不會有防止雜亂的自然方法 - 你知道什麼,忘記我說了什麼。 – 2012-02-17 21:23:21

+1

@KarlKnechtel:您必須指的是Python着名的「f \ * ck typing」。 – kindall 2012-02-18 00:18:46

3

type()可用於構造全新的類。你想要的是:

class Animal(): 
    def __init__(self, color): 
    self.color = color 

    def make_baby(self): 
    new_color = rand_color # a randomly chosen color 
    return self.__class__(new_color) 
+0

舊式課程,yuck。 'type(instance)'將返回一個具有新風格的類。 – 2012-02-17 20:48:59

+0

除非你使用Python 3當然,但他顯然不是。 – 2012-02-17 20:49:39

3

您的方法將完全工作!只要使用新的風格類。

Class Animal(object): 
    def __init__(self, color): 
    self.color = color 
    def make_baby(self): 
    new_color = rand_color # a randomly chosen color 
    return type(self)(new_color) 

Class Dog(Animal): 
    def pet(): 
    print '*pant*' 

Class Cat(Animal): 
    def pet(): 
    print 'purrr' 

但是,如果make_baby(self)依靠self細節,你想要的是一類範圍內的工廠方法,像@ Kindall的答案。

相關問題