Python子类丢失子类属性

时间:2015-11-02 18:26:28

标签: python python-2.7 inheritance attr shapely

这是基于shapely package的问题,但我认为这是一个更普遍的问题。

基本上我有两个课程来自于整齐。一个称为Point,另一个称为MultiPoint。您使用坐标元组实例化Point,使用MultiPoint列表Point实例化。您可以使用索引来访问多点中的点。

 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来解决这个问题?我想我不知道汽车(积分)传递给MultiPoint时会发生什么。

编辑:输入c1c2的代码示例时出错。它现在已经解决了。我没有实例化点数,我正在实例化汽车。

3 个答案:

答案 0 :(得分:3)

虽然MultiPoint类在概念上是Point的集合,但它实际上并未保留对Point实例(或Point实例的引用您传入其构造函数的子类。相反,它将坐标从该点复制到其自己的内部数据结构中。这会丢失您已添加到Car子类的额外属性。这是the docs中的简短段落:

  

构造函数还接受另一个MultiPoint实例或无序序列的Point个实例,从而制作副本。

我建议将Car类设计为具有Point的属性(或者可能是对MultiPoint和索引的引用),而不是制作它是Point的子类。当你可以使用封装时,继承另一个概念上不相关的类型通常是一个坏主意。

它可以帮助澄清您的设计,以便记住继承意味着&#34; IS-A&#34;,而封装意味着&#34; HAS-A&#34;。例如,一个矩形的IS-A形状,所以如果你写一个Shape类,Rectangle将是一个非常合理的子类。在您的情况下,您的继承表明Car IS-A Point,它没有多大意义。说Car HAS-A positionPoint)会更有意义。

答案 1 :(得分:1)

您应该使用Car类构造函数实例化Car个对象:

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

Python遵循鸭子类型原则:

  

如果它像鸭子一样嘎嘎叫,看起来像一只鸭子,那么它一定是一只鸭子   鸭。

这使得多态性变得非常容易。您的对象 不是任何特定的类,他们根据他们的超类行为。在不同情况下,这种行为可能会有所不同。

您的MultiPoint课程将接受CarPoint对象代替Point个对象。

我对你的data-side-pagination="server"课感到好奇,你能发帖吗?

答案 2 :(得分:1)

问题在于:

answer = new RadioButton[4];
radioGroup = new RadioGroup[4];
for (int i = 0; i < 4; i++) {
     radioGroup[i] = new RadioGroup(this);
     radioGroup[i].setOrientation(RadioGroup.VERTICAL);
     int j=0;
     for (Answer an : answers) {
         String answers_log = an.getAnswer();
         answer[j] = new RadioButton(this);
         answer[j].setText(answers_log);
         answer[j].setId(j);
         radioGroup[i].addView(answer[j]);
         j++;
     }
linearLayout.addView(radioGroup[i]);

根据描述,您必须实例化Car对象,而不是Points:

 c1 = Point((1,1), speed=2)
 c2 = Point((2,2), speed=3)
 mc = MultiPoint([c1,c2])
相关问题