如何使用python超类和继承(turtle graphics示例)?

kb5ga3dv  于 2023-10-21  发布在  Python
关注(0)|答案(2)|浏览(133)

我一直在玩海龟图形,试图更好地理解对象,我遇到了一个小问题。我已经学习了super()函数,并想使用它:

from turtle import Turtle, _Screen, Screen    

class turtle(Turtle):
    def __init__(self):
        super().__init__(shape="circle")            

wn = Screen()
tortoise = turtle()

所以如果我这么做,一切都会很顺利。我得到一个屏幕,我可以在我的turtle类上使用任何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()

这也将工作得很好,我得到了我所要求的:一个1000x1000的黑色窗口,在一个500x500的盒子里,带有滑动条。没问题.但是,如果我想把这些合并结合起来:

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()

它将显示屏幕,但我会从海龟得到一个错误:
属性错误:“_Screen”对象没有属性“_mode”
我一直在查看turtle模块,发现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

因此,我修改了Window类以包含以下内容:

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()

它的工作原理是这样的,我会得到一个白色窗口,与一个圆形的乌龟。但是如果我取消注解 * 设置 屏幕大小 * 或 bgcolor 部分,我会得到一个错误:
属性错误:“window”对象没有属性“tracing”

属性错误:“window”对象没有属性“cv”
因此,我必须再次在 *window * 类中的 *init
* 之前声明一些参数,以使其工作。我好像漏掉了什么。为什么turtle继承了所有的东西并且工作得很好,但是 _Screen 没有初始化所有必要的参数?

628mspwn

628mspwn1#

正如你所发现的,海龟Screen是一个有很多层的洋葱。我们需要解决两个问题:_Screen类调用它的super(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程序中。* 嵌入式 * 方法使用RawTurtleTurtleScreen和可选的Scrolled Canvas。这些类可能更容易子类化,更好的方法可能是通过在tkinter中嵌入turtle并根据需要子类化来构建自己的独立turtle。

vfhzx4xs

vfhzx4xs2#

在cdlane的回答之后,我发现我可以让它简单一点。Screen()部分可以在__init__函数中引入:

from turtle import Turtle, TurtleScreen, _Screen

class window(_Screen):
    def __init__(self):
        super().__init__()
        TurtleScreen.__init__(self, window._canvas)
        if Turtle._screen is None:
            Turtle._screen = self
        self.setup(500,500)
        self.screensize(1000,1000)
        self.title("Title")
        self.bgcolor("black")

class turtle(Turtle):
    def __init__(self):
        super().__init__(shape="circle")
        self.color("white")
        self.speed(0)
        self.circle(50)

wn = window()
tortoise = turtle()

再次感谢,伙计!

相关问题