如何在 python 中创建从 turtle 模块继承的子类
- 2025-02-20 09:22:00
- admin 原创
- 24
问题描述:
所以,我正在尝试学习 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 的子类。(下一步是让你的 turtle 表现得与标准 turtle 不同)
所以下面的评论让我想到也许我可以这样做:
import turtle
class TurtleGTX(turtle.Turtle):
"""My own version of turtle"""
my_turtle = TurtleGTX()
my_turtle.forward(100)
实际运行了!现在我要看看这会把我引向何方...有东西告诉我我可能前进了一步却后退了两步,因为这意味着我将无法初始化我的子类上的任何东西...
解决方案 1:
总结一下 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)
解决方案 2:
如果您在子类中重新定义一种方法(例如__init__()
),那么您有责任调用父类的方法以尊重父类的行为。
解决方案 3:
子类化并添加自定义功能是一种很诱人的模式Turtle
,例如turtle.jump()
。但我见过这种模式造成的大量问题,因此我对此持谨慎态度。
调用Turtle()
初始化程序(包括 的子类Turtle
)会将对象注册到 turtle 模块的内部 turtle 列表中。_update()
如果您不使用 禁用内部更新循环,则此列表会每帧调用一次turtle.tracer(0)
。此内部 turtle不太可能像您的子类所期望的那样被垃圾收集。
除了它们所关联的更新/绘制内部函数之外,Turtle
还有许多属性和方法,这些属性和方法的名称很容易与您的自定义属性和方法发生冲突(turtle 模块中大约有 150 个这样的名称,不包括双下划线)。当调用时,self.left()
可能很难记住这是对超类还是对派生类的 turtle 方法调用。通过将 turtle 组合为属性而不是子类,self.turtle.left()
可以使所有权完全清晰,但代价是有点冗长。
我也见过继承和组合混合在一起的情况,导致混乱的状态(文章末尾的示例)。
这里列出了继承的一些替代方法,其中一些仅用于特定目的,但为了完整性还是在这里列出:
如果您不介意海龟不被垃圾收集(您计划保留固定数量的海龟),您可以分配自定义类的实例,每个实例都有一个内部
self.turtle = Turtle()
实例,可以通过包装器以正常方式对其进行操作。这就是组合方法。
+ 由于您可能只使用少数几个 turtle 方法,因此您可以稍微妥协一下,`self.left(n)`在组合类上添加一个方法并委托给底层`self.turtle.left(n)`。这涉及添加一些额外的方法,但避免了继承的所有陷阱。
除了类之外,您还可以创建
Turtle
实例并将其传递给函数,以 C 风格的命令式方式执行操作:def jump(turtle, height): ...
。如果您计划创建某种粒子,这些粒子的创建和销毁频率相对较高,并且您只需要一个海龟来渲染而不是表示它们,那么您可以将粒子的内部表示和物理属性存储在一个类中,同时引用单个“笔”海龟。当需要绘制时,跟踪将被禁用,海龟会在所有共享粒子之间从一个位置移动到另一个位置,并根据需要进行绘制。
从理论上讲,这是一个很好的解决方案,但在实践中,我发现它对性能的影响太大,即使关闭了跟踪器。
自定义类可以从 Turtle 对象池中借用,从而帮助缓解垃圾收集问题。有关详细信息,请参阅为什么我的 Python Turtle 程序运行时间越长,速度就越慢?
话虽如此,如果有人提出反驳的话,我会很想看到一个有用的、非平凡的子类化模式案例。
以下是一些由 Turtle 子类化引起的混淆情况:
我该如何解决这个OOP乌龟游戏中的关键错误?
在 Python 3.11 Turtle Graphics 上按下按键后,我的 Pong 游戏中的桨叶不动
为什么屏幕中间有一个小箭头?
Turtle 子类“对象没有属性‘_shown’”
乒乓球游戏类继承混乱
AttributeError: 'Paddle' 对象没有属性 'screen'。您的意思是:'_screen'?
我的 Python 龟穿越游戏:碰撞函数不起作用
Python Turtle Graphics:使用 goto 时创建类错误
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)