python - 如何使用python超类和继承(海龟图形示例)?
问题描述
我一直在玩海龟图形,试图更好地理解对象,但遇到了一个小问题。我已经了解了 super() 函数并想使用它:
from turtle import Turtle, _Screen, Screen
class turtle(Turtle):
def __init__(self):
super().__init__(shape="circle")
wn = Screen()
tortoise = turtle()
所以如果我这样做,一切都会像魅力一样。我得到一个屏幕,我可以在我的龟类上使用任何龟方法。
from turtle import Turtle, _Screen, Screen
class window(_Screen):
def __init__(self):
super().__init__()
self.setup(500,500)
self.screensize(1000,1000)
self.title("Title")
self.bgcolor("black")
wn = window()
这也很好用,我得到了我的要求:在带有滑动条的 500x500 盒子中的 1000x1000 的黑色窗口。没问题。但是,如果我想结合这些:
from turtle import Turtle, _Screen, Screen
class window(_Screen):
def __init__(self):
super().__init__()
self.setup(500,500)
self.screensize(1000,1000)
self.title("Title")
self.bgcolor("black")
class turtle(Turtle):
def __init__(self):
super().__init__(shape="circle")
wn = window()
tortoise = turtle()
它会显示屏幕,但我会从海龟那里得到一个错误:
AttributeError:“_Screen”对象没有属性“_mode”
我一直在查看海龟模块,发现 Screen() 函数是这样做的:
def Screen():
"""Return the singleton screen object.
If none exists at the moment, create a new one and return it,
else return the existing one."""
if Turtle._screen is None:
Turtle._screen = _Screen()
return Turtle._screen
所以我修改了窗口类来包括这个:
from turtle import Turtle, _Screen, Screen
class window(_Screen):
def __init__(self):
Turtle._screen = Screen()
super().__init__()
#self.setup(500,500)
#self.screensize(1000,1000)
#self.title("Title")
#self.bgcolor("black")
class turtle(Turtle):
def __init__(self):
super().__init__(shape="circle")
wn = window()
tortoise = turtle()
它是这样工作的,我会得到一个白色的窗口,上面有一只圆乌龟。但是如果我取消注释setup、screensize或bgcolor部分,我会得到一个错误:
AttributeError:“窗口”对象没有属性“_tracing”
或者
AttributeError: 'window' 对象没有属性 'cv'
所以我必须再次在窗口类中的__init__之前声明一些参数,以使其工作。似乎我缺少一些东西。为什么乌龟继承了所有东西并且工作得很好,但是_Screen没有使用所有必要的参数进行初始化?
解决方案
正如您所发现的,乌龟Screen
是多层洋葱。有两个问题我们需要解决:_Screen
类调用它的超级(TurtleScreen)初始化器的方式对子类不友好;该Screen()
函数从很多地方调用,它硬编码创建屏幕的类。所以让我们解决这两个问题:
import turtle
class MyScreen(turtle._Screen):
def __init__(self):
super().__init__()
turtle.TurtleScreen.__init__(self, MyScreen._canvas)
self.setup(500, 500)
self.screensize(1000, 1000)
self.title("Title")
self.bgcolor("black")
def MyScreenFunction():
if turtle.Turtle._screen is None:
turtle.Turtle._screen = MyScreen()
return turtle.Turtle._screen
turtle.Screen = MyScreenFunction
class MyTurtle(turtle.Turtle):
def __init__(self):
super().__init__(shape="circle")
wn = turtle.Screen()
tortoise = MyTurtle()
tortoise.color('white')
tortoise.circle(100)
wn.mainloop()
但是,可能有更好的方法。Turtle 既可以像上面那样独立使用,也可以嵌入到 tkinter 程序中。嵌入式方法使用,RawTurtle
并且TurtleScreen
可选Scrolled Canvas
。这些类可能更容易子类化,更好的方法可能是通过在 tkinter 中嵌入 turtle 并根据需要进行子类化来构建您自己的独立海龟等价物。
推荐阅读
- python - 如何绘制多个树状图?
- flutter - 如何将 AdobeXD 精确原型转换为颤振
- java - 三个单元如何在 Analogic 中并行工作传入的工件载体?
- dataframe - 两个数据帧之间的欧式距离
- regex - 如何匹配以反斜杠开头的字符串,后跟 / 之类的问号?
= 用正则表达式 - python - 根据键在字典中查找值
- python - Python(CPython)中的最大可解析行长度是多少?
- python - 通过 python 3 在用户文件夹中搜索光栅图像文件的最有效方法是什么?
- .net - 在 Webview2 中使用 ExecuteScriptAsync 从网站中提取数据
- c# - 如何使用 Newtonsoft 反序列化 EPOCH