2014-04-05 51 views
1

我正在製作一個太陽系副本使用烏龜圖形。 我想製作一個恆星和一個既能從相同的烏龜超類「solar_element」繼承的星球,但我遇到了問題。如何使用烏龜超類

我可以使用兩種不同的海龜類的恆星和行星,沒有任何問題:

from turtle import Turtle 

class star(Turtle): 
    def __init__(self, Name, Radius, Mass, Colour): 
    Turtle.__init__(self, shape = "circle") 
    self.Name = Name 
    self.Radius = Radius 
    self.Mass = Mass 
    self.color(Colour) 
    self.shapesize(self.Radius/50) 

class planet(Turtle): 
def __init__(self, Name, Radius, Mass, Colour, Dist, velX, velY): 
    Turtle.__init__(self, shape= "circle") 
    self.Name = Name 
    self.Radius = Radius 
    self.Mass = Mass 
    self.color(Colour) 
    self.Dist = Dist 
    self.velX = velX 
    self.velY = velY 
    self.x_pos = sun.Radius + self.Dist + self.Radius 
    self.y_pos = 0 
    self.shapesize(self.Radius/50) 

sun = star('myStar', 500.0, 15000.0, "yellow"); 
earth = planet('P1', 150.0, 1000.0, "green", 0.25, 0.5, 2.0); 

但是,當我試圖讓他們從一個超類繼承,像這樣:

from turtle import Turtle 

class solar_element(Turtle): 
def __init__(self, Name, Radius, Mass, Colour): 
    self.Name = Name 
    self.Radius = Radius 
    self.Mass = Mass 
    self.Colour = Colour 
    self.color(self.Colour) 
    self.shapesize(self.Radius/50) 

class star(solar_element): 
def __init__(self, Name, Radius, Mass, Colour): 
    solar_element.__init__(self, Name, Radius, Mass, Colour) 
    Turtle.__init__(self, shape = "circle") 

class planet(solar_element): 
def __init__(self, Name, Radius, Mass, Colour, Dist, velX, velY): 
    solar_element.__init__(self, Name, Radius, Mass, Colour) 
    Turtle.__init__(self, shape = "circle") 
    self.Dist = Dist 
    self.velX = velX 
    self.velY = velY 
    self.x_pos = sun.Radius + self.Dist + self.Radius 
    self.y_pos = 0 

sun = star('myStar', 500.0, 15000.0, "yellow"); 
earth = planet('P1', 150.0, 1000.0, "green", 0.25, 0.5, 2.0); 

我得到以下錯誤:

Traceback (most recent call last): 
    File "C:\Users\Kev\Dropbox\OOP\testing_classes.py", line 62, in <module> 
    sun = star('myStar', 500.0, 15000.0, "yellow"); 
    File "C:\Users\Kev\Dropbox\OOP\testing_classes.py", line 47, in __init__ 
    solar_element.__init__(self, Name, Radius, Mass, Colour) 
    File "C:\Users\Kev\Dropbox\OOP\testing_classes.py", line 42, in __init__ 
    self.color(self.Colour) 
    File "C:\Python33\lib\turtle.py", line 2208, in color 
    pcolor = self._colorstr(pcolor) 
    File "C:\Python33\lib\turtle.py", line 2688, in _colorstr 
    return self.screen._colorstr(args) 
AttributeError: 'star' object has no attribute 'screen' 

我意識到我可以堅持兩個班,但我想使用超類,因爲我仍然在學習python。

+0

請寄上'Turtle'班。 –

+0

@Remolten你是什麼意思?我沒有其他任何東西可以發佈,代碼的第一部分可以嘗試。 – user3502196

+0

我的不好,忘了python有一個烏龜模塊。 –

回答

1

在調用solar_element構造函數之前,先調用Turtle構造函數,然後在starplanet類中調用構造函數。

因此改變你的代碼__init__方法star類來:

Turtle.__init__(self, shape = "circle") 
solar_element.__init__(self, Name, Radius, Mass, Colour) 

,改變你的代碼__init__方法planet類來:

Turtle.__init__(self, shape = "circle") 
solar_element.__init__(self, Name, Radius, Mass, Colour) 

起初,我們通常需要調用當我們想要覆蓋它時,方法中的基類的構造函數在__init__方法中。 實際上,我們最初稱之爲當我們想要使用__init__方法中的類的一部分時,這裏例如是color方法, 這個方法需要一些準備,在任何人都可以使用它之前執行。 這裏,例如screencolor方法Turtle需要設置之前,我們可以使用這種方法。

一些重構你的代碼:

  • 類名稱應該正常使用CapWords約定
  • 你不會在線路末端需要;
  • 變量名稱應該是小寫字母,必要時用下劃線分隔,以提高可讀性。
  • 使用的super(YourInheritedClass, self).__init__()代替 ParentClass.__init__(self)

代碼:

from turtle import Turtle 

class SolarElement(Turtle): 
    def __init__(self, name, radius, mass, colour, shape='circle'): 
     # or Turtle.__init__(self, shape=shape) 
     super(SolarElement, self).__init__(shape=shape) 
     self.name = name 
     self.radius = radius 
     self.mass = mass 
     self.colour = colour 
     self.color(self.colour) 
     self.shapesize(self.radius/50) 


class Star(SolarElement): 
    def __init__(self, name, radius, mass, colour, 
       shape='circle'): 
     SolarElement.__init__(self, name, radius, mass, colour, 
           shape=shape) 


class Planet(SolarElement): 
    def __init__(self, name, radius, mass, colour, dist, vel_x, vel_y, 
       shape='circle'): 
     SolarElement.__init__(self, name, radius, mass, colour, 
           shape=shape) 
     self.dist = dist 
     self.vel_x = vel_x 
     self.vel_y = vel_y 
     self.x_pos = sun.radius + self.dist + self.radius 
     self.y_pos = 0 

sun = Star('myStar', 500.0, 15000.0, "yellow") 
earth = Planet('P1', 150.0, 1000.0, "green", 0.25, 0.5, 2.0) 
+0

非常感謝你的工作,一個簡單的解決方案,我真的在發佈之前嘗試過。你能解釋爲什麼它以這種方式工作,而不是另一種? – user3502196

+0

我的答案已更新。 –

0

既然你獲得的Turtle一個子類,您需要初始化在子類__init__()方法的基類:

from turtle import Turtle 

class solar_element(Turtle): 
    def __init__(self, Name, Radius, Mass, Colour): 
     super(solar_element, self).__init__() 
     self.Name = Name 
     self.Radius = Radius 
     self.Mass = Mass 
     self.Colour = Colour 
     self.color(self.Colour) 
     self.shapesize(self.Radius/50) 

class star(solar_element): 
    def __init__(self, Name, Radius, Mass, Colour): 
     solar_element.__init__(self, Name, Radius, Mass, Colour) 
     Turtle.__init__(self, shape = "circle") 

class planet(solar_element): 
    def __init__(self, Name, Radius, Mass, Colour, Dist, velX, velY): 
     super(solar_element, self).__init__() 
     solar_element.__init__(self, Name, Radius, Mass, Colour) 
     Turtle.__init__(self, shape = "circle") 
     self.Dist = Dist 
     self.velX = velX 
     self.velY = velY 
     self.x_pos = sun.Radius + self.Dist + self.Radius 
     self.y_pos = 0 

sun = star('myStar', 500.0, 15000.0, "yellow") 
earth = planet('P1', 150.0, 1000.0, "green", 0.25, 0.5, 2.0) 
1

您遇到的問題是電話如果尚未調用Turtle類的__init__方法,則self.color(self.Colour)solar_object.__init__中不起作用。

您當前的代碼調用它調用solar_object.__init__Turtle.__init__後,所以在修復第一贓物是索性將首先調用它。

但是,我建議更改一些東西,並solar_object.__init__撥打電話Turtle.__init__。這樣,你不需要每個後來的子類都以正確的順序得到初始化器。

class solar_element(Turtle): 
    def __init__(self, Name, Radius, Mass, Colour): 
     Turtle.__init__(self, shape="circle") 
     # ... 

我還建議你瞭解super功能,Python提供了與調用你的超方法,而沒有具體命名他們的一種方式。您可以撥打super().__init__,而不是Turtle.__init__