2015-11-02 46 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