实现Turtle多线程

class Celsius(object):
    def __init__(self, value=0.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)

class Temperature(object):
    celsius = Celsius()

Why do I need the descriptor class? Please explain using this example or the one you think is better.

What is instance and owner here? (in get). So my question is, what is the purpose of the third parameter here?

How would I call/ use this example?

Answer:
The descriptor is how Python’s property type is implemented. A descriptor simply implements get, set, etc. and is then added to another class in its definition (as you did above with the Temperature class). For example:

temp=Temperature()
temp.celsius #calls celsius.get
Accessing the property you assigned the descriptor to (celsius in the above example) calls the appropriate descriptor method.

instance in get is the instance of the class (so above, get would receive temp, while owner is the class with the descriptor (so it would be Temperature).

You need to use a descriptor class to encapsulate the logic that powers it. That way, if the descriptor is used to cache some expensive operation (for example), it could store the value on itself and not its class.

An article about descriptors can be found here.

EDIT: As jchl pointed out in the comments, if you simply try Temperature.celsius, instance will be None.

descriptor: TurtleMethodCommand
pensize: accessing the property
class: TurtleCommander
instance: t
owner: TurtleCommander

目录threaded_turtle下的库文件:

cat init.py

"""
This package brings the functionality of Python's "turtle" package
with threading.

Turtle does not support threading, so this implements a queue which
serializes the access to turtle API from the main thread, which is
easily accessible from the turtle threads.

Usage:

# Initialize one TurtleThreadSerializer
ctrl = ThreadSerializer()

# Initialize TurtleThread instances as you want
# each represents a separate turtle, running in a separate thread

def run(my_turtle, angle):
    my_turtle.left(angle)
    for i in range(10, 0, -1):
        my_turtle.left(5)
        my_turtle.forward(i)

turtle1 = TurtleThread(ctrl, target=run, args=(0,))
turtle2 = TurtleThread(ctrl, target=run, args=(90,))
turtle3 = TurtleThread(ctrl, target=run, args=(180,))
turtle4 = TurtleThread(ctrl, target=run, args=(270,))


# Start all turtles:
turtle1.start()
turtle2.start()
turtle3.start()
turtle4.start()

# Start the main controller:
ctrl.run_forever()


"""
from threaded_turtle.thread_serializer import ThreadSerializer
from threaded_turtle.turtle_thread import TurtleThread

cat turtle_serializer.py

from turtle import Turtle
from threaded_turtle.thread_serializer import MethodCommand

class TurtleMethodCommand(MethodCommand):
    """The MethodCommand for Turtle commands

    Represents a method of turtle.Turtle.

    The class on which this is defined must have these two attributes:
     - turtle - instnce of Python built-in turtle.Turtle
     - thread_serializer - instance of ThreadSerializer

    """
    def _execute(self, threaded_turtle_instance, command_name, args, kwargs):
        threadless_turtle = threaded_turtle_instance.turtle

        method = getattr(threadless_turtle, command_name)
        return method(*args, **kwargs)

    def _get_thread_serializer(self, instance):
        return instance.thread_serializer


class TurtleCommander:
    def __init__(self, thread_serializer, turtle=None):
        self.thread_serializer = thread_serializer
        if turtle is None:
            self.turtle = Turtle()
        elif isinstance(turtle, TurtleCommander):
            self.turtle = turtle.turtle
        else:
            assert isinstance(turtle, Turtle)
            self.turtle = turtle

    forward = TurtleMethodCommand()
    fd = TurtleMethodCommand()
    backward = TurtleMethodCommand()
    bk = TurtleMethodCommand()
    back = TurtleMethodCommand()
    right = TurtleMethodCommand()
    rt = TurtleMethodCommand()
    left = TurtleMethodCommand()
    lt = TurtleMethodCommand()
    goto = TurtleMethodCommand()
    setpos = TurtleMethodCommand()
    setposition = TurtleMethodCommand()
    setx = TurtleMethodCommand()
    sety = TurtleMethodCommand()
    setheading = TurtleMethodCommand()
    seth = TurtleMethodCommand()
    home = TurtleMethodCommand()
    circle = TurtleMethodCommand()
    dot = TurtleMethodCommand()
    stamp = TurtleMethodCommand()
    clearstamp = TurtleMethodCommand()
    clearstamps = TurtleMethodCommand()
    undo = TurtleMethodCommand()
    speed = TurtleMethodCommand()
    position = TurtleMethodCommand()
    pos = TurtleMethodCommand()
    towards = TurtleMethodCommand()
    xcor = TurtleMethodCommand()
    ycor = TurtleMethodCommand()
    heading = TurtleMethodCommand()
    distance = TurtleMethodCommand()
    degrees = TurtleMethodCommand()
    radians = TurtleMethodCommand()
    pendown = TurtleMethodCommand()
    pd = TurtleMethodCommand()
    down = TurtleMethodCommand()
    penup = TurtleMethodCommand()
    pu = TurtleMethodCommand()
    up = TurtleMethodCommand()
    pensize = TurtleMethodCommand()
    width = TurtleMethodCommand()
    pen = TurtleMethodCommand()
    isdown = TurtleMethodCommand()
    color = TurtleMethodCommand()
    pencolor = TurtleMethodCommand()
    fillcolor = TurtleMethodCommand()
    filling = TurtleMethodCommand()
    begin_fill = TurtleMethodCommand()
    end_fill = TurtleMethodCommand()
    reset = TurtleMethodCommand()
    clear = TurtleMethodCommand()
    write = TurtleMethodCommand()
    showturtle = TurtleMethodCommand()
    st = TurtleMethodCommand()
    hideturtle = TurtleMethodCommand()
    ht = TurtleMethodCommand()
    isvisible = TurtleMethodCommand()
    shape = TurtleMethodCommand()
    resizemode = TurtleMethodCommand()
    shapesize = TurtleMethodCommand()
    turtlesize = TurtleMethodCommand()
    shearfactor = TurtleMethodCommand()
    settiltangle = TurtleMethodCommand()
    tiltangle = TurtleMethodCommand()
    tilt = TurtleMethodCommand()
    shapetransform = TurtleMethodCommand()
    get_shapepoly = TurtleMethodCommand()
    begin_poly = TurtleMethodCommand()
    end_poly = TurtleMethodCommand()
    get_poly = TurtleMethodCommand()
    clone = TurtleMethodCommand()
    getturtle = TurtleMethodCommand()
    getpen = TurtleMethodCommand()
    getscreen = TurtleMethodCommand()
    setundobuffer = TurtleMethodCommand()
    undobufferentries = TurtleMethodCommand()

cat thread_serializer.py

"""
Serialize thread execution using a queue.

When multiple thread are needed to be used in an environment where
multithreading is not supported, this module provides the functionality
for executing threads which send their commands to a queue which is then
executed sequentially in the main thread.

The functionality consists of:
- thread serializer - which puts commands in a queue when execute_command
                      is called from different threads, and then executes
                      the commands after reading them from the queue in the
                      main thread
- method command    - descriptor which creates a method to be called from a
                      thread; when called, the method creates a command in
                      thread serializer and waits for it to be executed, so
                      it seems as if it was executed within the thread
"""
import queue
import threading


class ThreadSerializer:
    """Sequentially executes commands it finds in its queue"""
    def __init__(self):
        self._queue = queue.Queue()

    def run_forever(self, queue_timeout=None):
        """Read commands from the queue and execute them forever

        If queue_timeout is given, this method will raise
        queue.Empty if there is noting in the queue for that number
        if seconds.
        """
        while True:
            command = self._queue.get(timeout=queue_timeout)
            command.execute()

    def execute_command(self, command):
        """Put command in the queue, wait for the result and return it"""

        self._queue.put(command)
        return command.wait_for_result()


class MethodCommand:
    """A descriptor which turns methods into commands

    Abstract class. Implement methods _execute and _get_thread_serializer:
    * _execute executes a command. It will always be executed from the main thread.
    * _get_thread_serializer return the thread serialized which executes commands

    Usage example:

        If a class defines a MethodCommand named foo, like this:

        class ClassTwo:
            foo = ImplementationOfMethodCommand()

        then foo can be called as a method and it will execute
        a command named "foo" with arguments passed to the method
    """

    def __init__(self, command_name=None):
        """
        Arguments:
            command_name: name of the command, defaults to the descriptor name

        """
        self._command_name = command_name

    def _execute(self, instance, command_name, args, kwargs):
        """Override this method. It should return a Command instance."""
        raise NotImplementedError()

    def _get_thread_serializer(self, instance):
        """Override this method. It should return a ThreadSerializer instance."""
        raise NotImplementedError()

    def _get_redirected_func(self, instance):
        serializer = self._get_thread_serializer(instance)
        def func(*a, **kw):
            execute = lambda: self._execute(instance, self._command_name, a, kw)

            return serializer.execute_command(_Command(execute))
        func.__qualname__ = "command<{}>".format(self._command_name)
        return func

    def __get__(self, instance, owner):
        if instance is not None:
            return self._get_redirected_func(instance)
        else:
            def unbound_f(inst, *a, **kw):
                bound_f = self._get_redirected_func(inst)
                return bound_f(*a, **kw)
            unbound_f.__qualname__ = "unbound command<{}>".format(self._command_name)
            return unbound_f

    def __set_name__(self, owner, name):
        if self._command_name is None:
            self._command_name = name


class _Command:
    """A command to be executed in another thread"""

    def __init__(self, execute_callback):
        self._result_ready_event = threading.Event()
        self._result = None
        self._execute_callback = execute_callback

    def execute(self):
        self._result = self._execute_callback()
        self._result_ready_event.set()

    def wait_for_result(self):
        self._result_ready_event.wait()
        return self._result

cat turtle_thread.py

import threading
from threaded_turtle.turtle_serializer import TurtleCommander


class TurtleThread(threading.Thread):
    """A thread which knows how to handle a turtle ;)

    The constructor takes two additional arguments compared to vanilla Thread:
     - thread_serializer - the object which makes it possible to
                           run turtles in threads
     - turtle            - the optional turtle.TurtleCommander, if omitted,
                           a new one will be created

    There are two main ways to use it:
    - if the thread is implemented by overriding the run method, use self.turtle
      as if it was a normal turtle.Turtle which can run in a thread
    - if the thread is initialized with a "target" argument, the target will
      receive the turtle as the first argument, plus all args and kwargs

    """
    def __init__(self, thread_serializer, turtle=None, target=None, name=None,
                 args=(), kwargs={}, daemon=None):
        self.turtle = TurtleCommander(thread_serializer, turtle)
        if target is not None:
            args = (self.turtle,) + tuple(args)
        super().__init__(target=target, name=name, args=args, kwargs=kwargs, daemon=daemon)

主程序:

# coding=utf-8
import turtle
from threaded_turtle import ThreadSerializer, TurtleThread
from datetime import *
import math as m
turtle.colormode(255)
turtle.delay(0)






def Skip(step):
    turtle.penup()
    turtle.forward(step)
    turtle.pendown()
 
 
def mkHand(name, length):
    # 注册Turtle形状,建立表针Turtle
    turtle.reset()
    Skip(-length * 0.1)
    # 开始记录多边形的顶点。当前的乌龟位置是多边形的第一个顶点。
    turtle.begin_poly()
    turtle.forward(length * 1.1)
    # 停止记录多边形的顶点。当前的乌龟位置是多边形的最后一个顶点。将与第一个顶点相连。
    turtle.end_poly()
    # 返回最后记录的多边形。
    handForm = turtle.get_poly()
    turtle.register_shape(name, handForm)
 
 
def Init():
    global secHand, minHand, hurHand, printer
    # 重置Turtle指向北
    turtle.mode("logo")
    # 建立三个表针Turtle并初始化
    mkHand("secHand", 135)
    mkHand("minHand", 125)
    mkHand("hurHand", 90)
    secHand = turtle.Turtle()
    secHand.shape("secHand")
    minHand = turtle.Turtle()
    minHand.shape("minHand")
    hurHand = turtle.Turtle()
    hurHand.shape("hurHand")
 
    for hand in secHand, minHand, hurHand:
        hand.shapesize(1, 1, 3)
        hand.speed(0)
 
        # 建立输出文字Turtle
    printer = turtle.Turtle()
 
    # 隐藏画笔的turtle形状
    printer.hideturtle()
    printer.penup()
 
 
def SetupClock(radius):
    # 建立表的外框
    turtle.reset()
    turtle.pensize(7)
    turtle.pencolor("#ff5500")
    turtle.fillcolor("green")
 
    for i in range(60):
        Skip(radius)
        if i % 5 == 0:
            turtle.forward(20)
            Skip(-radius - 20)
 
            Skip(radius + 20)
            if i == 0:
                turtle.write(int(12), align="center", font=("Courier", 14, "bold"))
            elif i == 30:
                Skip(25)
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
                Skip(-25)
            elif (i == 25 or i == 35):
                Skip(20)
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
                Skip(-20)
            else:
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
            Skip(-radius - 20)
        else:
            turtle.dot(5)
            Skip(-radius)
        turtle.right(6)
 
 
def Week(t):
    week = ["星期一", "星期二", "星期三",
            "星期四", "星期五", "星期六", "星期日"]
    return week[t.weekday()]
 
 
def Date(t):
    y = t.year
    m = t.month
    d = t.day
    return "%s-%d-%d" % (y, m, d)
 
 
def Tick():
    # 绘制表针的动态显示
    t = datetime.today()
    second = t.second + t.microsecond * 0.000001
    minute = t.minute + second / 60.0
    hour = t.hour + minute / 60.0
    secHand.setheading(6 * second)
    minHand.setheading(6 * minute)
    hurHand.setheading(30 * hour)
 
    turtle.tracer(False)
 
    printer.forward(65)
    printer.write(Week(t), align="center",
                  font=("Courier", 14, "bold"))
    printer.back(130)
    printer.write(Date(t), align="center",
                  font=("Courier", 14, "bold"))
    printer.home()
    turtle.tracer(True)
 
    # 100ms后继续调用tick
    turtle.ontimer(Tick, 100)
 
 
def main():
    # 打开/关闭龟动画,并为更新图纸设置延迟。
#    turtle.tracer(False)
    turtle.speed(0)
    Init()
    SetupClock(160)
    turtle.tracer(True)
    Tick()
    turtle.mainloop()
 








turtle.mode("standard")

ctrl = ThreadSerializer()                        ## <-- create a serializer
t1=turtle.Turtle()
t2=turtle.Turtle()
t2.right(0)
t2.pu()
t6=turtle.Turtle()
t6.right(45)
t6.pu()
t7=turtle.Turtle()
t7.right(90)
t7.pu()
t8=turtle.Turtle()
t8.right(135)
t8.pu()
t9=turtle.Turtle()
t9.right(180)
t9.pu()
t10=turtle.Turtle()
t10.right(225)
t10.pu()
t11=turtle.Turtle()
t11.right(270)
t11.pu()
t12=turtle.Turtle()
t12.right(315)
t12.pu()
t4=turtle.Turtle()
t1.screen.setup(width=1500, height=900)
t1.pu()
t4.pu()
t1.speed(0)
#t2.speed(6)
t4.speed(0)
t4.goto(-100, -100)
t1.goto(-400, 200)
t2.goto(200, 100)
t6.goto(200, 100)
t7.goto(200, 100)
t8.goto(200, 100)
t9.goto(200, 100)
t10.goto(200, 100)
t11.goto(200, 100)
t12.goto(200, 100)




def tes1(t1):
    t1.pensize(4) # 设置画笔的大小
    t1.color("Hotpink", "pink") # 设置画笔颜色和填充颜色(pink)
#    t1.speed(0) # 设置画笔速度为10
    #鼻子
    t1.pu() # 提笔
#    t1.goto(-100,100) # 画笔前往坐标(-100,100)
    t1.pd() # 下笔
    t1.seth(-30) # 笔的角度为-30°
    t1.begin_fill() # 外形填充的开始标志
    a=0.4
    for i in range(120):
       if 0<=i<30 or 60<=i<90:
           a=a+0.08
           t1.lt(3) #向左转3度
           t1.fd(a) #向前走a的步长
       else:
           a=a-0.08
           t1.lt(3)
           t1.fd(a)
    t1.end_fill() # 依据轮廓填充
    t1.pu() # 提笔
    t1.seth(90) # 笔的角度为90度
    t1.fd(25) # 向前移动25
    t1.seth(0) # 转换画笔的角度为0
    t1.fd(10)
    t1.pd()
    t1.pencolor("HotPink") # 设置画笔颜色
    t1.seth(10)
    t1.begin_fill()
    t1.circle(5) # 画一个半径为5的圆
    t1.color("Brown") # 设置画笔和填充颜色
    t1.end_fill()
    t1.pu()
    t1.seth(0)
    t1.fd(20)
    t1.pd()
    t1.pencolor("HotPink")
    t1.seth(10)
    t1.begin_fill()
    t1.circle(5)
    t1.color("Brown")
    t1.end_fill()
    #头
    t1.color("HotPink","pink")
    t1.pu()
    t1.seth(90)
    t1.fd(41)
    t1.seth(0)
    t1.fd(0)
    t1.pd()
    t1.begin_fill()
    t1.seth(180)
    t1.circle(300,-30) # 顺时针画一个半径为300,圆心角为30°的园
    t1.circle(100,-60)
    t1.circle(80,-100)
    t1.circle(150,-20)
    t1.circle(60,-95)
    t1.seth(161)
    t1.circle(-300,15)
    t1.pu()
    t1.goto(-400,200)
    t1.pd()
    t1.seth(-30)
    a=0.4
    for i in range(60):
       if 0<=i<30 or 60<=i<90:
           a=a+0.08
           t1.lt(3) #向左转3度
           t1.fd(a) #向前走a的步长
       else:
           a=a-0.08
           t1.lt(3)
           t1.fd(a)
    t1.end_fill()
    #耳朵
    t1.color("HotPink","pink")
    t1.pu()
    t1.seth(90)
    t1.fd(-7)
    t1.seth(0)
    t1.fd(70)
    t1.pd()
    t1.begin_fill()
    t1.seth(100)
    t1.circle(-50,50)
    t1.circle(-10,120)
    t1.circle(-50,54)
    t1.end_fill()
    t1.pu()
    t1.seth(90)
    t1.fd(-12)
    t1.seth(0)
    t1.fd(30)
    t1.pd()
    t1.begin_fill()
    t1.seth(100)
    t1.circle(-50,50)
    t1.circle(-10,120)
    t1.circle(-50,56)
    t1.end_fill()
    #眼睛
    t1.color("HotPink", "white")
    t1.pu()
    t1.seth(90)
    t1.fd(-20)
    t1.seth(0)
    t1.fd(-95)
    t1.pd()
    t1.begin_fill()
    t1.circle(15)
    t1.end_fill()
    t1.color("black")
    t1.pu()
    t1.seth(90)
    t1.fd(12)
    t1.seth(0)
    t1.fd(-3)
    t1.pd()
    t1.begin_fill()
    t1.circle(3)
    t1.end_fill()
    t1.color("HotPink", "white")
    t1.pu()
    t1.seth(90)
    t1.fd(-25)
    t1.seth(0)
    t1.fd(40)
    t1.pd()
    t1.begin_fill()
    t1.circle(15)
    t1.end_fill()
    t1.color("black")
    t1.pu()
    t1.seth(90)
    t1.fd(12)
    t1.seth(0)
    t1.fd(-3)
    t1.pd()
    t1.begin_fill()
    t1.circle(3)
    t1.end_fill()
    #腮
    t1.color("HotPink")
    t1.pu()
    t1.seth(90)
    t1.fd(-95)
    t1.seth(0)
    t1.fd(65)
    t1.pd()
    t1.begin_fill()
    t1.circle(30)
    t1.end_fill()
    #嘴
    t1.color("red")
    t1.pu()
    t1.seth(90)
    t1.fd(15)
    t1.seth(0)
    t1.fd(-100)
    t1.pd()
    t1.seth(-80)
    t1.circle(30,40)
    t1.circle(40,80)
    #身体
    t1.color("red")
    t1.pu()
    t1.seth(90)
    t1.fd(-20)
    t1.seth(0)
    t1.fd(-78)
    t1.pd()
    t1.begin_fill()
    t1.seth(-130)
    t1.circle(100,10)
    t1.circle(300,30)
    t1.seth(0)
    t1.fd(230)
    t1.seth(90)
    t1.circle(300,30)
    t1.circle(100,3)
    t1.color("Red")
    t1.seth(-135)
    t1.circle(-80,63)
    t1.circle(-150,24)
    t1.end_fill()
    #手
    t1.color("HotPink")
    t1.pu()
    t1.seth(90)
    t1.fd(-40)
    t1.seth(0)
    t1.fd(-27)
    t1.pd()
    t1.seth(-160)
    t1.circle(300,15)
    t1.pu()
    t1.seth(90)
    t1.fd(15)
    t1.seth(0)
    t1.fd(0)
    t1.pd()
    t1.seth(-10)
    t1.circle(-20,90)
    t1.pu()
    t1.seth(90)
    t1.fd(30)
    t1.seth(0)
    t1.fd(237)
    t1.pd()
    t1.seth(-20)
    t1.circle(-300,15)
    t1.pu()
    t1.seth(90)
    t1.fd(20)
    t1.seth(0)
    t1.fd(0)
    t1.pd()
    t1.seth(-170)
    t1.circle(20,90)
    #脚
    t1.pensize(10)
    t1.color("Tomato")
    t1.pu()
    t1.seth(90)
    t1.fd(-75)
    t1.seth(0)
    t1.fd(-180)
    t1.pd()
    t1.seth(-90)
    t1.fd(40)
    t1.seth(-180)
    t1.color("black")
    t1.pensize(15)
    t1.fd(20)
    t1.pensize(10)
    t1.color("Tomato")
    t1.pu()
    t1.seth(90)
    t1.fd(40)
    t1.seth(0)
    t1.fd(90)
    t1.pd()
    t1.seth(-90)
    t1.fd(40)
    t1.seth(-180)
    t1.color("black")
    t1.pensize(15)
    t1.fd(20)
    #尾巴
    t1.pensize(4)
    t1.color("Pink")
    t1.pu()
    t1.seth(90)
    t1.fd(70)
    t1.seth(0)
    t1.fd(95)
    t1.pd()
    t1.seth(0)
    t1.circle(70,20)
    t1.circle(10,330)
    t1.circle(70,30)




"""
def test2(t2):
    t2.speed(1)
    t2.pd()
    t2.pensize(30)
    t2.pencolor("green")
    t2.seth(-40)    # 前进的方向
    for _ in range(2):
        t2.circle(70, 80)
        t2.circle(-70, 80)
    t2.circle(70, 40)
    t2.forward(35)  # 直线前进
    t2.circle(15, 180)
    t2.forward(70/4)


def tes2(t2):                                    ## <-- additional argument
    t2.pensize(4) # 设置画笔的大小
    t2.color("black") # 设置画笔颜色和填充颜色(pink)
#    t2.speed(0) # 设置画笔速度为10
    t2.pu() # 提笔
    t2.pd() # 下笔
    t2.seth(-90)
    a=10
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+0.5
           t2.lt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-0.5
           t2.lt(5)
           t2.fd(a)
    t2.pu()
    t2.seth(0)
    t2.fd(40)
    t2.seth(90)
    t2.fd(100)
    t2.seth(120)
    t2.color('black')
    t2.begin_fill()
    t2.pd()
    t2.circle(-50,180)
    t2.end_fill()
    t2.heading()
    t2.pu()
    t2.seth(0)
    t2.fd(100)
    t2.seth(60)
    t2.color('black')
    t2.begin_fill()
    t2.pd()
    t2.circle(-50,180)
    t2.end_fill()
    t2.pos()
    t2.pu()
    t2.goto(200,215)
    t2.seth(-30)
    t2.pd()
    t2.begin_fill()
    
    a=1
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+0.2
           t2.lt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-0.2
           t2.lt(5)
           t2.fd(a)
    
    
    
    
    
    t2.end_fill()
    t2.goto(220, 255)
    t2.dot(15, "white")
    t2.pu()
    t2.goto(350,215)
    t2.seth(30)
    t2.pd()
    t2.begin_fill()
    a=1
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+0.2
           t2.lt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-0.2
           t2.lt(5)
           t2.fd(a)
    
    t2.end_fill()
    t2.pu()
    t2.goto(325, 255)
    t2.dot(15, "white")
    t2.goto(280,170)
    t2.dot(40, "black")
    t2.goto(220, 130)
    t2.seth(-40)
    t2.pd()
    t2.circle(100,80)
    t2.pu()
    t2.goto(210, 80)
    t2.seth(-30)
    t2.begin_fill()
    t2.pd()
    
    
    a=6
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+0.1
           t2.rt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-0.1
           t2.rt(5)
           t2.fd(a)
    
    
    t2.end_fill()
    t2.pu()
    t2.goto(350,100)
    t2.seth(30)
    t2.begin_fill()
    t2.pd()
    a=3
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+0.5
           t2.rt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-0.5
           t2.rt(5)
           t2.fd(a)
    
    
    
    t2.end_fill()
    t2.pu()
    t2.goto(80,-80)
    t2.seth(-180)
    t2.begin_fill()
    t2.pd()
    t2.circle(80,180)
    t2.circle(1380,7)
    t2.circle(50,80)
    t2.seth(90)
    t2.fd(70)
    t2.seth(170)
    t2.circle(1400,9)
    t2.end_fill()
    t2.pu()
    t2.goto(520, -90)
    t2.seth(0)
    t2.begin_fill()
    t2.pd()
    t2.circle(-70,180)
    t2.circle(-1380,7)
    t2.circle(-50,60)
    t2.seth(90)
    t2.fd(70)
    t2.seth(10)
    t2.circle(-1400,9)
    t2.end_fill()
   
    a=2
    for i in range(72):
       if 0<=i<18 or 36<=i<54:
           a=a+1
           t2.lt(5) #向左转3度
           t2.fd(a) #向前走a的步长
       else:
           a=a-1
           t2.lt(5)
           t2.fd(a)
    
    t2.end_fill()


"""



def test3(t4):

    t4.pensize(4) # 设置画笔的大小
#    t4.colormode(255) # 设置GBK颜色范围为0-255
    t4.color((0,0,255),"blue") # 设置画笔颜色和填充颜色(pink)
#    t4.setup(800,600) # 设置主窗口的大小为840*500
    t4.speed(0) # 设置画笔速度为10
    #头部
    t4.hideturtle()
    t4.pu() # 提笔
    t4.goto(-50,-400) # 画笔前往坐标(0,0)
    t4.seth(150)
    t4.pd() # 下笔
    t4.begin_fill()
    t4.color(0,0,255)
    for i in range(75):
      t4.rt(4)
      t4.forward(2*m.pi*100/90)
    t4.seth(0)
    t4.backward(10)
     
    t4.seth(30)
    for i in range(75):
      t4.lt(4)
      t4.forward(2*m.pi*80/90)
    t4.seth(0)
    t4.backward(10)
    t4.end_fill()
    #眼睛
    t4.pu()
    t4.begin_fill()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(-15,40*m.sqrt(3)+60-400)
    t4.pd()
    t4.circle(15)
    t4.color(255,255,255)
    t4.end_fill()
     
    t4.pu()
    t4.begin_fill()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(-15,40*m.sqrt(3)+60-400)
    t4.pd()
    t4.circle(5)
    t4.color(0,0,0)
    t4.end_fill()
     
    t4.pu()
    t4.begin_fill()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(15,40*m.sqrt(3)+60-400)
    t4.pd()
    t4.circle(15)
    t4.color(255,255,255)
    t4.end_fill()
     
    t4.pu()
    t4.begin_fill()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(15,40*m.sqrt(3)+60-400)
    t4.pd()
    t4.circle(5)
    t4.color(0,0,0)
    t4.end_fill()
     
     
    #鼻子
    t4.pu()
    t4.pensize(3)
    t4.pencolor(255,0,0)
    t4.goto(0,40*m.sqrt(3)+40-400)
    t4.pd()
    t4.begin_fill()
    t4.color(255,0,0)
    t4.circle(10)
    t4.end_fill()
    #嘴巴
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(0,40*m.sqrt(3)+40-400)
    t4.pd()
    t4.seth(-90)
    t4.forward(50)
    t4.pu()
    t4.goto(-50,90-10*m.sqrt(3)-400)
    t4.seth(-30)
    t4.pd()
    for i in range(30):
     t4.lt(2)
     t4.forward(2*m.pi*100/180)
      
      
    #胡须
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(-30,40*m.sqrt(3)+25-400)
    t4.seth(0)
    t4.pd()
    t4.backward(40)
     
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(-30,40*m.sqrt(3)+15-400)
    t4.pd()
    t4.seth(30)
    t4.backward(40)
     
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(-30,40*m.sqrt(3)+35-400)
    t4.pd()
    t4.seth(-30)
    t4.backward(40)
     
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(30, 40*m.sqrt(3)+25-400)
    t4.seth(0)
    t4.pd()
    t4.forward(40)
     
     
     
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(30,40*m.sqrt(3)+35-400)
    t4.pd()
    t4.seth(30)
    t4.forward(40)
     
    t4.pu()
    t4.pensize(3)
    t4.pencolor(0,0,0)
    t4.goto(30,40*m.sqrt(3)+15-400)
    t4.pd()
    t4.seth(-30)
    t4.forward(40)
     
    # a=0.4
    # for i in range(360):
       # if 0<=i<90 or 180<=i<270:
           # a=a+0.008
           # t4.lt(1) #向左转3度
           # t4.fd(a) #向前走a的步长
       # else:
           # a=a-0.008
           # t4.lt(1)
           # t4.fd(a)
#    t4.done()



def test2(t2):
#    
#    t2.pd()
    
#    t = [t2 for i in range(8)]
#    print("t is:", t)

#    for i, j in enumerate(t2):
#        j.right(i*45)
    t2.pd()
    t2.speed(0)

    for i in range(360):
        t2.forward(1)
        t2.right(1)





 






t = TurtleThread(ctrl, t1, target=tes1)          ## <-- additional arguments
t.daemon = True
t.start()

t3 = TurtleThread(ctrl, t2, target=test2)         ## <-- additional arguments
t3.daemon = True
t3.start()


t13 = TurtleThread(ctrl, t6, target=test2)         ## <-- additional arguments
t13.daemon = True
t13.start()

t14 = TurtleThread(ctrl, t7, target=test2)         ## <-- additional arguments
t14.daemon = True
t14.start()

t15 = TurtleThread(ctrl, t8, target=test2)         ## <-- additional arguments
t15.daemon = True
t15.start()

t16 = TurtleThread(ctrl, t9, target=test2)         ## <-- additional arguments
t16.daemon = True
t16.start()

t17 = TurtleThread(ctrl, t10, target=test2)         ## <-- additional arguments
t17.daemon = True
t17.start()

t18 = TurtleThread(ctrl, t11, target=test2)         ## <-- additional arguments
t18.daemon = True
t18.start()

t19 = TurtleThread(ctrl, t12, target=test2)         ## <-- additional arguments
t19.daemon = True
t19.start()

t5 = TurtleThread(ctrl, t4, target=test3)
t5.daemon = True
t5.start()



#
try:

    ctrl.run_forever(0)
    
except:
    main()


t1.screen.exitonclick()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来给你讲一下多线程龟兔赛跑的实现。 首先,我们需要创建两个线程,一个代表乌龟,一个代表兔子。每个线程都有一个速度参数,代表它们每次前进的距离。同时,我们需要创建一个共享变量,代表比赛的距离。比赛开始时,乌龟和兔子同时出发,不断地向前移动,直到比赛结束。 在比赛过程中,我们需要不断地更新比赛距离,并且判断是否有一方到达终点。如果有一方到达终点,我们就可以停止比赛。此外,为了避免线程冲突,我们需要使用互斥锁来保护共享变量。 下面是一个简单的多线程龟兔赛跑的代码示例: ```python import threading import time import random # 定义比赛距离 distance = 100 # 定义乌龟线程 class Turtle(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.speed = 1 def run(self): global distance while distance > 0: # 乌龟前进 distance -= self.speed print("乌龟跑了1米,距离终点还有{}米".format(distance)) time.sleep(0.1) print("乌龟到达终点,比赛结束!") # 定义兔子线程 class Rabbit(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.speed = 2 def run(self): global distance while distance > 0: # 兔子前进 distance -= self.speed print("兔子跑了2米,距离终点还有{}米".format(distance)) time.sleep(0.1) print("兔子到达终点,比赛结束!") # 创建乌龟和兔子线程,并启动比赛 turtle = Turtle() rabbit = Rabbit() turtle.start() rabbit.start() ``` 希望这个简单的示例能够帮助你理解多线程龟兔赛跑的实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值