如何在python中创建继承自turtle模块的子类

问题描述 投票:0回答:3

所以,我正在尝试学习 python,每次我在这里发布问题都感觉像是屈服......

我正在尝试创建自己的 turtle.Turtle 类。

    import turtle
class TurtleGTX(turtle.Turtle):
    """My own version of turtle"""
    def __init__(self):
        pass

my_turtle = TurtleGTX()
my_turtle.forward(10)

给出回溯:AttributeError:“TurtleGTX”对象没有属性“_position”。然后我了解到这是一个“私有变量”,根据官方 python 教程,我可以在我的子类 TurtleGTX 中修改/覆盖它。如何用像 turtle 这样大的程序来做到这一点似乎相当困难,这意味着我缺少一个更简单的问题解决方案。最后我学到了,这就是重点,但我仍然希望由社区运行它,看看是否有一种优雅的方法来创建 turtle.Turtle 的子类。 (下一步是让你的乌龟表现得与标准乌龟不同)

所以下面的评论让我觉得也许我可以这样做:

import turtle
class TurtleGTX(turtle.Turtle):
    """My own version of turtle"""


my_turtle = TurtleGTX()
my_turtle.forward(100)

实际运行!现在我要看看它会把我引向何方……有些事情告诉我,我可能已经向前迈了一步,向后退了两步,因为这意味着我将无法在我的子类上初始化任何东西……

python inheritance subclass turtle-graphics python-turtle
3个回答
9
投票

总结 Ignacio 的回答和 orokusaki 的评论,你可能应该写类似的东西

import turtle
class TurtleGTX(turtle.Turtle):
    """My own version of turtle"""
    def __init__(self,*args,**kwargs):
        super(TurtleGTX,self).__init__(*args,**kwargs)
        print("Time for my GTX turtle!")

my_turtle = TurtleGTX()
my_turtle.forward(100)

3
投票

如果您在子类中重新定义一个方法(例如

__init__()
),那么您有责任调用父类的方法以尊重父类的行为。


1
投票

继承

Turtle
并添加自定义功能(例如
turtle.jump()
)是一种诱人的模式。但我在这种模式上取得的成功有限,在大多数情况下我都会谨慎行事。

调用

t = Turtle()
(包括
Turtle
的子类)将对象注册到海龟模块的内部海龟列表中。如果您不使用
_update()
禁用内部更新循环,则此列表每帧都会调用
turtle.tracer(0)
。这个内部乌龟不太可能像您的子类所期望的那样收集垃圾.

除了它们挂钩的更新/绘制内部结构外,

Turtle
有许多属性和方法可以很容易地与您的自定义属性和方法命名冲突(海龟模块中大约有 150 个这样的名称,不包括双下划线) .当调用
self.left()
时,可能很难记住这是对超类还是派生类的 turtle 方法调用。通过将 turtle 组合为一个属性而不是一个子类,
self.turtle.left()
使所有权完全清晰,代价是有点冗长。

这里有一组继承的替代方案,其中一些只对特定目的有用,但为了完整性还是列在这里:

  • 如果你不介意海龟没有被垃圾收集(你正在制作一个你计划保留的固定数量),你可以分配一个自定义类的实例,每个实例都有一个内部

    self.turtle = Turtle()
    实例从包装器以正常方式操作。这是composition方法。

    • 由于您可能只使用了少数几种 turtle 方法,因此您可以稍微妥协并在组合类上添加一个
      self.left(n)
      方法,并 delegate 到底层
      self.turtle.left(n)
      。这涉及添加一些额外的方法,但避免了继承的所有陷阱。
  • 您可以创建

    Turtle
    实例并将它们传递给使它们以 C 风格命令式方式执行操作的函数,而不是类:
    def jump(turtle, height): ...
    .

  • 如果您计划创建某种相对频繁创建和销毁的粒子,并且您只需要一只乌龟来渲染而不是表示它们,您可以将粒子的内部表示和物理属性存储在一个类中,同时引用一个单“笔”龟。当需要绘制时,跟踪被禁用,乌龟在所有共享粒子中从一个位置移动到下一个位置,根据需要绘制。

    理论上,这是一个很好的解决方案,但在实践中,我发现即使关闭跟踪器,它也会对性能产生太大影响。

  • 自定义类可以从海龟的对象池中借用,有助于缓解垃圾收集问题。有关详细信息,请参阅为什么我的 Python Turtle 程序运行时间越长,速度会急剧下降?

就是说,如果有人有的话,我很想看到一个有用的、不平凡的子类模式案例。

© www.soinside.com 2019 - 2024. All rights reserved.