2014-04-05 53 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__