2015-11-02 90 views
0

這是基於shapely package的問題,但我認爲這是一個更普遍的問題。Python子類失去子類屬性

基本上我有兩個類來自勻稱。一個叫做Point,另一個叫MultiPoint。您使用座標元組實例化Point,使用Point列表MultiPoint。您可以使用索引訪問多點中的點。

p1 = Point((1,1)) 
p2 = Point((2,2)) 
mp = MultiPoint([p1,p2]) 

In [315]: MultiPoint((p1, p2))[0] 
Out[315]: <shapely.geometry.point.Point at 0x1049b1f50> 

我想要子類Point並將其用於汽車的位置。現在

class Car(Point): 
    def __init__(self, coords, speed): 
     super(self.__class__, self).__init__(coords) 
     self.speed = speed 

我可以寫

c1 = Car((1,1), speed=2) 
c2 = Car((2,2), speed=3) 
mc = MultiPoint([c1,c2]) 

我可以使用索引訪問的汽車,但他們不再是汽車。他們是點。特別是他們沒有屬性速度。

In [316]: MultiPoint((c1, c2))[0] 
Out[316]: <shapely.geometry.point.Point at 0x1049b1610> 

In [317]: MultiPoint((c1, c2))[0].speed 
AttributeError: 'Point' object has no attribute 'speed' 

有沒有一種方法通過子類化多點?我想我不知道汽車(點)在傳遞給MultiPoint時會發生什麼。

編輯:我輸入c1c2的代碼示例時輸入錯誤。現在已經修復了。我沒有實例化點,我正在實例化汽車。

+0

你的「現在我可以寫」的例子應該是調用'Car'而不是'Point'嗎?如果是這樣,我懷疑這個問題的答案完全取決於MultiPoint是如何實現的。如果它只包含傳入它的對象,則應該能夠使其工作。但是,如果它將通過'Point'實例的座標解包並將它們放入其他類型的數據結構(可能是C數組)中,那麼您可能不太順利。 – Blckknght

+0

@Blckknght。感謝您指出我的錯誤。它是固定的。我有點懷疑我可能不走運。我想我正在尋找指導組織原則。 – Ben

回答

3

雖然MultiPoint類是概念上的Point秒的集合,它是實際上並沒有保留對你傳遞給它的構造函數的Point實例(或者Point子類的實例)的引用。相反,它會將點的座標複製到它自己的內部數據結構中。這會失去添加到Car子類中的額外屬性。下面是the docs簡短的一段話:

構造函數也接受另一MultiPoint實例或Point實例的無序順序,從而使副本。

我建議您設計Car類有一個屬性一個Point(或者一個參照MultiPoint和索引),而不是使之成爲Point一個子類。當你可以使用封裝代替時,繼承另一個概念上不相關的類型通常是一個壞主意。

它可以幫助澄清你的設計,記住繼承意味着「IS-A」,而封裝意味着「HAS-A」。例如,一個矩形的IS-A形狀,所以如果你寫一個Shape類,Rectangle將是一個完全合理的子類。在你的情況下,你的繼承意味着一個Car IS-A Point,這沒有多大意義。說一個Car HAS-A position(這是一個Point)會更有意義。

+0

好的。這是一個很好的記憶範例,非常有幫助。如果我將一個Point屬性添加到汽車,我可以向後走並使用一個點來訪問它屬於的汽車實例。我問,因爲我想問一些關於汽車位置的問題 - 例如。附近有什麼車? – Ben

1

你應該實例化Car對象與Car類的構造函數:

c1 = Car((1,1), speed=2) 
c2 = Car((2,2), speed=3) 
mc = MultiPoint([c1,c2]) 

的Python如下鴨打字原則:

如果它叫起來像鴨子,看起來像鴨子,那麼它必須是一隻 鴨。

這使得多態性非常容易。你的對象沒有任何特定的類,他們根據他們的超類行爲。這種行爲在不同情況下可能會有所不同。

您的MultiPoint類將會傾聽接受Car對象代替Point對象。

我很好奇你的Point班,你可以發貼嗎?

+0

我輸入示例代碼時出錯。我的意思是它的讀取與你寫的完全相同。它仍然不能很好地適應'MultiPoint'。我的問題現在已修復。對於那個很抱歉。 – Ben

+0

發佈你的要點類 –

+0

點類來自[勻稱包](http://toblerity.org/shapely/shapely.geometry.html#module-shapely.geometry.point)。 – Ben

1

的問題是在這裏:

c1 = Point((1,1), speed=2) 
c2 = Point((2,2), speed=3) 
mc = MultiPoint([c1,c2]) 

根據描述,你必須實例化租車對象,而不是積分:

c1 = Car((1,1), 2) 
c2 = Car((2,2), 3) 
+0

對不起。這在打字時是一個錯誤。我修正了這個例子。 – Ben