【问题标题】:How to use a turtle superclass如何使用海龟超类
【发布时间】:2014-05-18 05:58:48
【问题描述】:

我正在使用海龟图形制作太阳系复制品。 我想制作一个都继承自同一个海龟超类“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。

【问题讨论】:

  • 请发布Turtle 课程。
  • @Remolten 你是什么意思?我没有其他要发布的,代码的第一部分可以尝试。
  • 我的错,忘了python有一个turtle模块。

标签: python class inheritance superclass turtle-graphics


【解决方案1】:

在您的starplanet 类中,在调用solar_element 构造函数之前首先调用Turtle 构造函数。

因此,将star 类的__init__ 方法中的代码更改为:

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

并将planet 类的__init__ 方法中的代码更改为:

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)

【讨论】:

    【解决方案2】:

    您遇到的问题是,如果尚未调用 Turtle 类的 __init__ 方法,solar_object.__init__ 中的调用 self.color(self.Colour) 将无法正常工作。

    您当前的代码调用Turtle.__init__ 它调用solar_object.__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__

    【讨论】:

      【解决方案3】:

      由于您要派生Turtle 的子类,因此您需要在子类__init__()methods 中初始化基类:

      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)
      

      【讨论】:

        猜你喜欢
        • 2019-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-19
        相关资源
        最近更新 更多