2013-09-24 238 views
3

我有以下示例設置:Python類繼承初始化

class Feet: 
    def __init__ (self, value = 0.0): 
     self.value = value 
     self.units = "f" 

    def feet(self): 
     return self.value 


class Meters: 
    def __init__(self, value = 0.0): 
     self.value = value 
     self.units = "m" 

    def feet(self): 
     # This is probably not an accurate conversion. 
     return self.value * 2.54 * 10 


class Distance (Feet, Meters): 
    def __init__(self, type = Feet()): 
     Feet.__init__(self) 
     Meters.__init__(self) 
     print type.feet() -- Prints 254.0 
     self = type 
     print self.feet() -- Prints 254.0 

dist = Distance(Meters(10.0)) 

print dist.units -- Prints = "m" 
print dist.value -- Prints = 0.0 
print dist.feet() -- Prints = 0.0 

我似乎無法理解爲什麼當我初始化類的米類類型,並指定10.0,我不守10.0。然而單位似乎保持正確。我是否錯過了關於如何設置的內容?

我的理解是,我正在創建Meters的「實例」,並將其分配給Distance的「self」變量。如果自我價值無法修改,我可以理解我的單位是否爲「f」,但我的單位是「m」,因此顯然將Meters類分配給自己,但它沒有采用實例化的值,我發現它很奇怪。

說實話我甚至不知道我會在這種情況下谷歌,所以我很抱歉我沒有做很多谷歌搜索,大部分我發現並不適用於這種類型的問題。

此外,我的計劃是基本上將它「鑄造」爲相同類型,無論您通過哪種方式,例如對於腳,我將返回Feet類的自實例,並且在Meters類中,我將返回Feet (self.Value * 2.54 * 10)所以我會永遠有我的腳距離。

所以腳腳變得

def feet(self): 
    return self 

爲米英尺變得

def feet(self): 
    return Feet(self.value * 2.54 * 10) 

重述一遍,有沒有我可以在1 2類通過在初始化過程中的理由,但它不需要我的初始化參數爲該類?

我真的不清楚爲什麼我可以在距離類中指定「自我」,並在返回之前出現有正確的初始化,但返回後它不起作用。

+0

您正在重新定義所有方法。你的前兩個類有相同的方法。您從兩者繼承,所以第二個類的方法覆蓋第一個類的方法 – Paco

回答

5

事情是,你是從2類繼承英尺和米。兩個類都有相同的方法。在你Distance.__init__()方法,你在做的時候覆蓋英尺與米方法的方法是:

Feet.__init__(self) 
    Meters.__init__(self) 

什麼,我會做不同:

class Distance(object): 
    def __init__(self, meters=None, feet=None): 
     self.feet = feet 
     self.meters = meters 

然後,你可以這樣做:

distance = Distance(meters=Meters(12)) 
print distance.meters.value 
print distance.meters.type 
# Here do whatever you want with them 

您可以同時傳遞兩個對象。如果兩個對象都不是None,那麼使用 做一些其他的事情。

+0

當我刪除這兩種情況時,我沒有「屬性」單元,那麼如果有意義的話,如何「初始化」類?我只是嘗試鍵入.__ init __(self),但是當我打印「type.feet()」時,它將作爲* instance和float的非端口操作數類型出現,但.value應該是一個浮點數,而不是一個實例。 – onaclov2000

+0

在這種情況下,你不應該繼承2類,我會用另一個編輯我的答案 – Paco

2

這裏完全沒有理由從腳或米繼承,更不用說這兩者。這是一個經典的構圖案例,而不是繼承,尤其是因爲您將單位類作爲參數傳遞。刪除那個子類,並在__init__你可以做self.type = type

1

其他答案涵蓋了你繼承的問題,但沒有涵蓋你重新登錄self

在一個方法(如__init__)中,self只是一個綁定到實例的本地名。你完全可以自由地重新命名這個名字,但這只是讓self引用別的東西。 它不影響實例

在這種情況下,當__init__返回self名字超出範圍,但原始實例分配給dist就好像你沒有反彈的名字self

請注意,__init__是一個初始化程序,而不是構造函數。 Python也允許你爲一個類定義一個自定義的構造函數(__new__),並且構造函數可以改變返回的對象。但是你不需要在這裏使用它。

0

這條線:

self = type 

沒有做什麼,你認爲它。你認爲這是一個賦值語句,其中self提到的對象具有type(la C++)的屬性。

Python沒有與其他語言具有相同意義的賦值。

該行的作用是將本地名稱self綁定到type當前綁定的對象。它在Distance.__init__()以外絕對沒有效果,並且對先前綁定的對象幾乎沒有影響。