news 2026/10/13 21:53:25

Python turtle绘图全实例:从螺旋到分形与排序动画

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python turtle绘图全实例:从螺旋到分形与排序动画

说实话,很多人一听说 turtle 绘图,第一反应就是“给小学生玩的玩具”。但真正用 Python 写过几个实例之后,你会发现它几乎是学习编程逻辑最好的可视化工具:循环、函数、递归、坐标、角度、随机数,这些东西在 turtle 里全都变成了看得见摸得着的东西。这篇文章围绕 turtle 绘图多个实例展开,从最简单的正方形螺旋、五角星,一路画到科赫雪花、分形树和冒泡排序可视化,把每个图形的原理、代码和踩坑点都拆开讲,不管你是有基础的程序员,还是刚学 Python 的新手,都能直接照着敲出自己想要的效果。

选 turtle 还有一层现实原因:它是 Python 标准库自带的模块,不需要安装任何第三方包,打开编辑器就能用。就算你的环境里连 pip 都懒得配,turtle 也永远在那里等着你。更重要的是,turtle 的绘图逻辑和真实图像处理、动画渲染、游戏开发里的坐标系概念是相通的。搞懂了 turtle,后面学 Pygame、Tkinter Canvas,甚至任何图形库的屏幕坐标换算,都会顺很多。

1. 动手前的必修课:turtle 的坐标系与画笔状态

1.1 turtle 到底是怎么想问题的

turtle 源自早期的 Logo 语言,核心思想很简单:屏幕上有一只海龟,你给它下命令,它就拖着笔移动。forward(100) 往前走 100 像素,right(90) 向右转 90 度,就这么朴素。这种“给指令,看结果”的模式,天然适合理解程序执行的顺序和状态变化。

很多人一上来就背 API 列表,效果其实不好。我更推荐你先记住三个问题:海龟现在在哪?海龟面朝哪个方向?要不要落笔?只要把这三个状态想清楚,turtle 里九成命令都能推出来。比如你想让海龟画一条从屏幕左上角到右下角的线,第一件事绝对不是找画线函数,而是先把海龟抬起来、移过去、定好方向、再落笔画线。

1.2 画布坐标系:一张有原点的无限方格纸

turtle 的窗口默认是横向 800 像素、纵向 600 像素(不同环境可能有差异),坐标原点在画布正中心,水平向右是 x 轴正方向,垂直向上是 y 轴正方向,单位是像素。也就是说,左上角坐标是 (-400, 300),右下角是 (400, -300),正中心是 (0, 0)。

这个坐标系和数学里的平面直角坐标系几乎一样,唯一的区别是 y 轴方向没有“反转”,往上就是正的,这比很多图形库亲民。绘图时常用的思路是先 penup() 抬笔,goto(x, y) 移动到目标点,再 pendown() 落笔开始画,这样就不会在移动过程中留下痕迹。初学阶段最容易犯的错就是忘了抬笔,结果画出一条贯穿整个窗口的对角线。

1.3 画笔的四个核心状态

画图之前,建议先把画笔状态调整到自己想要的样子。我每次写新实例都会先做三件事:调速度、调颜色、调笔宽,免得画到一半才发现线太细看不清。

  • 位置:通过 goto(x, y) 控制,配合 penup()/pendown() 决定移动时是否留痕。
  • 朝向:初始朝向右(0 度),left(90) 会向上转,right(90) 会向下转。setheading() 可以直接指定绝对角度,90 度朝上、180 度朝左、270 度朝下。
  • 颜色与笔宽:color('red') 设置线条颜色,pensize(3) 设置画笔粗细。想用 RGB 方式调色,先执行 colormode(255),再用 color(200, 50, 50) 这类写法。
  • 速度:speed(0) 是最高速,speed(1) 最慢,speed(6) 是默认。动画演示的时候故意调慢,正式出图的时候果断 speed(0)。

顺带提一个新手必踩的坑:程序运行完,窗口常常一闪而过。解决办法是在代码最后加 turtle.done() 或者 turtle.exitonclick(),前者保持窗口打开,后者是点击窗口才关闭。“画完了窗口马上消失”几乎是 turtle 新手遇到的第一道坎,一定要记得收尾。

1.4 每个实例的公共初始化代码

后续所有实例我都会先跑这一段公共初始化

import turtle t = turtle.Turtle() t.speed(0) t.pensize(2) turtle.delay(0) turtle.colormode(255) turtle.setup(width=800, height=600)

turtle.delay(0) 会让每一条绘图指令之间的刷新间隔变为 0,配合 speed(0) 之后,图形基本是瞬间画完的。setup 设置窗口尺寸,避免小窗显示不下。要注意 delay 和 speed 是两套机制,speed 控制海龟移动快慢的等级,delay 控制每步动画的毫秒间隔,两者都调成最快才不会有明显的拖拽感。

2. 简单几何实例:循环、变量与图形的第一层关系

2.1 正方形螺旋:一条循环语句里的数学

画正方形很简单,循环四次 forward + right(90) 就行。但正方形螺旋不一样,每一圈的边长都在变大,它把一个非常核心的数学思想摆到了你面前:通过循环变量不断更新绘图参数。

import turtle t = turtle.Turtle() t.speed(0) turtle.delay(0) for i in range(60): t.forward(5 + i * 4) t.right(90) turtle.done()

这个例子的关键在 forward(5 + i * 4),边长从 5 开始,每多循环一次就增加 4 像素。start 值 5 决定初始边长,step 值 4 决定边长增速。如果 step 太小,螺旋圈与圈之间会贴得很近,看起来像一整块实心方块;如果 step 太大,螺旋又会有明显的断档感,不太像连续的曲线。

我建议你改参数前先做一个简单预测:step 从 4 改成 10,画出来的螺旋每圈间隙会变大,图形整体也会比较松散。这种“改参数前先猜结果,再运行验证”的习惯,比单纯抄代码有用得多。

2.2 旋转风车:角度差决定图案密度

同样是循环画线,把“边长递增”换成“每次转不同角度”,得到的就是风车效果。这里不需要落笔移动两次,直接 forward 到终点再原路退回来即可。

import turtle t = turtle.Turtle() t.speed(0) turtle.delay(0) turtle.colormode(255) colors = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue'] for i in range(30): t.setheading(i * 12) t.color(colors[i % len(colors)]) t.forward(160) t.backward(160) turtle.done()

每次绘图前用 setheading(i * 12) 强制设置绝对角度,相当于把每一根线条都视为“从原点向某个方向画一条半径”。30 根线,每根间隔 12 度,刚好绕满一圈。如果把 12 改成 15,线的数量变成 24 根;改成 13,角度不再整除 360,第二圈会和第一圈错开,最终形成更复杂的星芒图案。

这个实例很适合用来理解“角度步长”这个概念。数学上 360 度乘以重复次数如果不是 360 的整数倍,图案就会产生旋转偏移,这在后面做五角星和多边形的时候还会遇到。

2.3 五角星:转向角到底怎么算

画五角星几乎每个人都想当然地写出 right(72),因为 360 / 5 = 72,结果画出来是个正五边形。五角星的正确转角是 144 度,这个数从哪来?五角星每个外顶点处,两条边之间的内角是 36 度,海龟沿着边走到顶点后,需要右转的角度等于 180 - 36 = 144 度。

import turtle t = turtle.Turtle() t.speed(0) turtle.delay(0) for _ in range(5): t.forward(200) t.right(144) turtle.done()

这里的规律可以推广:要画一个角数为 n 的星形,先算出星形外角对应的内角,再用 180 减去它。更重要的是理解“转向角是外角,不是中心角”这一事实。海龟画多边形是把外角依次转完,外角和恒等于 360 度,所以正 n 边形每次转 360 / n。而带尖角的星形每次跨过的是一条更长的弧,转角要按星形特有的角度计算,直接用 360 / n 会得到完全不同的图形。

2.4 一个小表,记住常见转向角对应的图形

真正动手画的时候,不需要每次都推公式,但至少要有一个大概的直觉。

转向角图形效果说明
90 度正方形、矩形、方形螺旋最简单,容易验证循环变量
72 度正五边形360 / 5
60 度正六边形、蜂窝状结构适合做组合拼接
144 度五角星注意不是 72
120 度等边三角形、六角雪花局部转向角大于 90 会产生尖锐折返
整数倍错开的角度星芒、花形、退化成线循环次数与 360 不成整数比时

这张表可以帮助快速判断一个图形到底该用哪个角度。尤其在排查“为什么画出来不是我想象的形状”时,先检查转角,大概率问题就出在这里。

3. 分形实例:三行递归画出科赫雪花

3.1 递归不止是“自己调自己”

很多初学者看到递归就头疼,其实递归只需要抓住两件事:基例和递归步。基例就是“最简单、不能再拆的情况”,递归步则是“把大问题拆成小问题的规则”。在 turtle 里面,这两件事都非常直观。

拿画一条直线来说。如果递归深度是 0,直接 forward 画直线,这就是基例。如果深度大于 0,就把这条直线拆成更小的单元,先画一部分,转向,再画另一部分,在中间插入折线结构,这样就把原来的一条直线替换成了更复杂的图案。分形之所以迷人,是因为同样的替换规则在每一层递归里都会重新执行一次,图案的细节会呈指数级增长。

3.2 科赫雪花:把直线的一小段改成凸起的折线

科赫雪花的生成规则是:把一条线段三等分,中间那段去掉,换成一个没有底边的等边三角形,形成向外凸起的尖角。然后把这条更复杂的折线再按相同规则细分,反复执行。

import turtle def koch(t, length, depth): if depth == 0: t.forward(length) return length = length / 3 koch(t, length, depth - 1) t.left(60) koch(t, length, depth - 1) t.right(120) koch(t, length, depth - 1) t.left(60) koch(t, length, depth - 1) t = turtle.Turtle() t.speed(0) turtle.delay(0) t.penup() t.goto(-200, 100) t.pendown() for _ in range(3): koch(t, 400, 3) t.right(120) turtle.done()

第一次调用 koch(t, 400, 3),length 变成 400 / 3,然后进入四段递归。每一段又继续把长度除以 3 再调用。所以多层递归之后,海龟实际前进的最小段长度是 400 / (3^depth),depth 为 3 时大约是 14.8 像素。理论上深度越大,雪花边缘越精细,但速度也会指数级下降。depth 到 6 的时候,单条边会被拆成 4^6 = 4096 段,整个雪花超过 12000 次移动指令,跑起来明显变长。实战中画雪花,depth 取 4 到 5 最合适,画面既细腻又不太慢。

3.3 分形树:树枝的角度与收缩比

分形树的思路和科赫雪花类似,但方向不同:它不是把直线拆成折线,而是从树干顶端分出两个子树枝,每个子树枝又继续分叉。

import turtle def tree(t, length, depth): if depth == 0: return t.forward(length) t.left(30) tree(t, length * 0.7, depth - 1) t.right(60) tree(t, length * 0.7, depth - 1) t.left(30) t.backward(length) t = turtle.Turtle() t.speed(0) turtle.delay(0) t.penup() t.goto(0, -250) t.pendown() t.left(90) tree(t, 120, 6) turtle.done()

tree 函数的核心秘密在最后的 backward(length)。每画完一层递归,海龟必须原路退回树干分叉点,才能继续画另一侧的树枝。这个“先前进画树枝,再后退回溯”的模式是大多数分形树代码的关键。如果忘了后退,海龟的状态就乱了,画出来的图案会像一团乱麻。

两个参数值得特别把玩:角度和收缩比。角度 30 度决定两棵子树之间的夹角是 60 度,角度越大,树冠越展开;收缩比 0.7 决定每一层树枝长度递减的速度,收缩比接近 1 的时候树冠非常稠密,接近 0.5 的时候树形稀疏、瘦长。我给初学者的建议是先固定收缩比 0.7,然后尝试角度 20、30、45 三个值,观察树冠形态的变化,会发现 45 度的树更接近一把打开的伞,20 度的树更趋近圆锥形。

3.4 谢尔宾斯基三角形:三个小三角形拼出一个大镂空

谢尔宾斯基三角形是另一个非常炸裂的递归实例:一个大等边三角形,挖掉中心的倒三角,剩下三个角上的小三角形,然后每个小三角形再继续同样的挖空操作。

import turtle def sierpinski(t, x, y, size, depth): if depth == 0: t.penup() t.goto(x, y) t.pendown() t.begin_fill() for _ in range(3): t.forward(size) t.left(120) t.end_fill() return half = size / 2 h = half * (3 ** 0.5) / 2 sierpinski(t, x, y, half, depth - 1) sierpinski(t, x + half, y, half, depth - 1) sierpinski(t, x + half / 2, y + h, half, depth - 1) t = turtle.Turtle() t.speed(0) turtle.delay(0) t.color('black') sierpinski(t, -200, -150, 400, 4) turtle.done()

这里没有用常规的“先把大三角画出来再挖空”的思路,而是直接递归三个小三角的绘制。坐标计算要稍微推一下:如果大三角形的左下角是 (x, y),边长 size,那么左边子三角形的左下角还是 (x, y),右边子三角形的左下角是 (x + size/2, y),上方子三角形的左下角是 (x + size/4, y + size√3/4)。每次递归把 size 减半,三块子区域同时更新,到 depth 为 0 时画出实心三角。

填充的时候要注意 begin_fill 和 end_fill 必须成对出现,而且 begin_fill 之前最好 penup 到多边形的起点,否则海龟走过了一段隐藏路径,填充区域会多出一块不该有的部分。depth=4 会画出 4^4 = 256 个小三角形,已经非常有分形的味道了。

4. 综合实例:太极、彩虹与星空场景

4.1 太极图的圆盘叠加法

太极图看起来像是一笔画挑战,但用 turtle 画最稳的方法不是画一条连续 S 形曲线,而是用圆盘叠加。简单说就是:先画一个黑色大圆,再用白色半圆盖住左边一半,接着在右上补一个白圆,在左下补一个黑圆,最后点两个眼睛。这个方法思路直白,完全不依赖复杂的海龟转向。

import turtle t = turtle.Turtle() t.speed(0) turtle.delay(0) R = 100 # 画黑色大圆 t.color('black', 'black') t.penup() t.goto(0, -R) t.setheading(0) t.pendown() t.begin_fill() t.circle(R) t.end_fill() # 用白色半圆覆盖左半部分 t.color('black', 'white') t.penup() t.goto(0, -R) t.setheading(90) t.pendown() t.begin_fill() t.circle(-R, 180) t.end_fill() # 在右上角覆盖一个白色小圆 t.penup() t.goto(0, R) t.setheading(0) t.pendown() t.begin_fill() t.circle(-R / 2, 180) t.end_fill() # 在左下角补一个黑色小圆 t.color('black', 'black') t.penup() t.goto(0, -R) t.setheading(0) t.pendown() t.begin_fill() t.circle(R / 2, 180) t.end_fill() # 画两个鱼眼 t.penup() t.goto(0, R / 2) t.dot(R / 6, 'black') t.goto(0, -R / 2) t.dot(R / 6, 'white') turtle.done()

这里最需要注意 circle 参数的正负号:circle(radius, angle) 中 radius 为正时海龟向逆时针方向画圆,radius 为负时向顺时针方向画圆。从同一个起点、同一个朝向出发,circle(100, 180) 画的是右半圆,circle(-100, 180) 画的是左半圆。我反复强调这一点,是因为程序中三个半圆的方向很容易写反,一旦写反,得到的图案就变成了镜像版太极,转 180 度倒是能用,但初学者很容易被绕晕。

4.2 彩虹与同心圆环

彩虹实例最直观的做法是画一组同心圆:每画一个整圆,把半径增大一定的量,同时换一种颜色。由于每根圆环之间是紧密相邻的,加大 pensize 之后视觉上就是一条条彩带。

import turtle t = turtle.Turtle() t.speed(0) turtle.delay(0) turtle.colormode(255) colors = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple'] t.pensize(15) for i, c in enumerate(colors): t.color(c) t.penup() t.goto(0, -(80 + i * 25)) # 让圆心保持在原点 t.pendown() t.circle(80 + i * 25) turtle.done()

关键点在于 t.circle(radius) 默认把圆心放在海龟左侧 radius 处。如果海龟停在 (0, 0) 直接画圆,圆心会跑到 (0, -radius),根本不是以原点为中心。所以每次要先把海龟移到 (0, -radius),朝向默认的 0 度,再画圆,这样圆心才会回到原点。这是一个非常容易忽略的细节,也是很多新手画同心圆画成一堆乱圆的根本原因。

如果想画半圆彩虹而不是整圈,可以给 circle 加第二个参数:t.circle(radius, 180)。这时候注意起点位置同样决定了半圆的方向,想画出向上拱的彩虹弧,起点应该放在画面下方,比如 (0, -150) 朝上画。我在实际教学中发现,整圆彩虹适合作为“学习圆环绘制”的入门,半圆彩虹则适合做“理解起点和朝向关系”的进阶练习。

4.3 星空场景:随机数与画笔的配合

turtle 配合 random 模块能做出很有氛围的星空图。思路很简单:在画布范围内随机取坐标,随机设置大小和亮度,用 dot() 画点,再叠加一个黄色圆作为月亮。

import turtle import random t = turtle.Turtle() t.speed(0) turtle.delay(0) turtle.bgcolor('black') turtle.colormode(255) t.penup() for _ in range(150): x = random.randint(-380, 380) y = random.randint(-280, 280) size = random.randint(1, 4) brightness = random.randint(180, 255) t.goto(x, y) t.dot(size, (brightness, brightness, random.randint(100, 255))) # 画月亮 t.goto(-200, 180) t.color('yellow', 'yellow') t.begin_fill() t.circle(40) t.end_fill() turtle.done()

dot 和 circle 的区别值得单独说:dot(size, color) 画的是一个独立的点,不需要落笔、没有路径计算,效率远超 circle,画几百个星星毫无压力;circle 则是真正意义上的绘制轮廓并填充,适合画月亮这种有边界感的大物体。散点类效果一律用 dot,构图、背景、装饰才用 circle。

星空这类实例适合反复改参数:把星星数量从 150 改成 500,画面会从清冷变成浓密;把 brightness 门槛从 180 提高到 230,星星会更暗更柔。最重要的还是看到随机数参与绘图后,每次运行都会得到不同的画面。

4.4 给所有实例加上平滑移动的小细节

综合实例经常会遇到“海龟从一个点飞到另一个点”的情况,这时候默认的直线移动会留下一条难看的斜线。我的习惯是:所有长距离移动都先 penup,到达目标点后再 pendown。书写代码时,把“抬笔-移动-落笔”当成一个固定动作来写:

t.penup() t.goto(x, y) t.pendown()

这个三连在复杂图形里非常提升画面整洁度。此外,想让构图对称美观,可以在 setup 阶段就把主图形规划在窗口中心区域,比如太极图半径 100 放在边长 800 的窗口里就显得比较空,半径 180 左右会更饱满。动手画之前看一眼坐标范围,能省掉很多后期调整的麻烦。

5. 排序过程可视化:turtle 的动力学玩法

5.1 从静态到动态:tracer 与 update 的妙用

前面所有实例都是画完一张静态图,要么看结果,要么保存图片。但 turtle 真正的隐藏能力在于动画:你可以一边修改数据,一边把中间状态画出来。很多人不知道 turtle.tracer(0) 这个开关的用途。

tracer(0) 的意思是关闭海龟逐帧刷新,所有绘图指令不会立刻显示到窗口里,直到你调用 update(),屏幕上才会一次性更新当前帧。这相当于一个离屏渲染机制。如果不关闭 tracer,每画一条线窗口就刷新一次,排序可视化那几百根柱子会闪到怀疑人生;关闭之后,每一帧稳定更新一次,动画非常干净。

5.2 冒泡排序的可视化实现

用 turtle 演示冒泡排序,本质上就是“每次数据交换后重画一遍所有柱形”。代码不长,但把排序算法、列表交换、绘图函数三件事结合到了一起,非常有挑战性。

import turtle import random import time turtle.setup(width=800, height=600) turtle.tracer(0) turtle.delay(0) data = [random.randint(30, 200) for _ in range(20)] t = turtle.Turtle() t.speed(0) t.penup() def draw_bars(): turtle.clear() for i, h in enumerate(data): x = i * 20 - 190 y = -150 t.goto(x, y) t.setheading(90) t.pendown() t.begin_fill() t.forward(h) t.right(90) t.forward(12) t.right(90) t.forward(h) t.right(90) t.forward(12) t.end_fill() t.penup() turtle.update() time.sleep(0.05) draw_bars() for i in range(len(data) - 1): for j in range(len(data) - i - 1): if data[j] > data[j + 1]: data[j], data[j + 1] = data[j + 1], data[j] draw_bars() turtle.done()

绘制柱形时,我用了“从底部向上画高,然后向右转 90 度画宽,再向下画回底部”的方式。begin_fill 会自动把最后一点连回起点,形成闭合矩形,所以不用手动画第四个边。开始时把海龟定位到 (x, y),也就是柱形左下角,setheading(90) 让它朝上,然后 forward 画高度。每一步数据交换后调用 draw_bars 重画,就能看到最高的柱子在慢慢“冒泡”到右侧。

这里要注意 time.sleep 不能省,也不能太长。sleep 0.05 秒在 20 根柱子、约 190 次内层循环下,总时长大概 10 秒,节奏刚好;如果数据量加到 50,sleep 就要缩到 0.02 秒,否则等待时间让人很难受。tracer(0) 配合 sleep,才能既看清过程又不卡顿。

5.3 提速与效果平衡的几个小经验

排序可视化最大的坑是“绘制速度远慢于算法速度”。算法本身瞬间就能跑完,但每轮都要重画 20 根柱子,如果你在每轮循环里都调用一次 draw_bars,动画会显得非常快,难以观察。我的处理方法是先跑一遍逻辑,数一下总共有多少帧,再反推 sleep 值。比如 20 个数据冒泡排序总共要比较约 190 次,我想让动画在 10 秒左右结束,就设置 sleep 为 10 / 190 ≈ 0.05 秒,实测效果非常舒适。

另外,排行榜式的条形图也可以换一种画法:只重画发生交换的两根柱子,而不是清空重画全部。这样做代码会复杂一些,但性能会好很多,适合数据量上百的场景。不过作为学习实例,清空重画的好处是逻辑直观、不容易出错,等你看懂了再优化也不迟。

排序可视化这个玩法对我个人来说是 turtle 从“画图工具”升级为“教学工具”的分水岭。在此之前,turtle 只是不断输出静态结果;在此之后,你会发现它能把任何可以用列表表示的数据变化过程,转化成生动的动画。我把同样的模式稍加改造,还做过选择排序和插入排序的可视化,只需要替换排序算法里的比较交换部分,绘图函数完全不用动。

最后再分享一个小技巧:分形和动画类实例特别适合把关键参数做成变量,比如递归深度、分支角度、sleep 时间。我在调试科赫雪花时,一般先用 depth=2 快速验证逻辑,确认没问题再逐步提高到 5。跑排序动画时,也是先用 10 个数据把流程跑通,再上真实数据量。这个“小规模验证,再放大参数”的习惯,能帮你避开很多 turtle 绘图里最让人抓狂的问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 21:53:00

Java DAO层测试优化:连接池复用与事务回滚实战

1. 项目概述在Java企业级应用开发中,DAO(Data Access Object)层作为数据持久化的核心组件,其稳定性和可靠性直接影响整个系统的质量。然而在实际开发中,DAO层测试往往面临连接泄漏、事务污染、测试耦合度高等典型问题。…

作者头像 李华
网站建设 2026/10/13 21:52:43

本地化AI开发系统:30天构建可验证、可交付的离线工作流

1. 这不是“学AI工具”,而是一次系统性能力迁移很多人看到标题里“30天”“AI开发系统”这几个词,第一反应是:又一个速成班广告?或者——是不是要从零开始写大模型?其实都不是。我用这30天干了一件更实在的事&#xff…

作者头像 李华
网站建设 2026/10/13 21:51:12

让代码学会“看情况办事”:Python分支与循环精讲

程序这东西,很多初学者刚接触的时候都会有一个错觉:程序不就是从上到下、一行一行按顺序执行吗?这说的没错,但那只是最基础的顺序结构。真实世界里没有哪款软件是纯直线跑下来的——你点外卖时,程序要根据订单金额判断…

作者头像 李华
网站建设 2026/10/13 21:50:36

Python装饰器全解析:原理、进阶与实战经验

装饰器这东西,我第一次接触的时候是在某个同事的代码里看到一个符号摆在一个函数头上,当时第一反应是“这是什么魔法?”。后来自己动手写了一个带参数的装饰器,才恍然大悟——其实它没那么玄乎,就是“函数套函数”的语…

作者头像 李华
网站建设 2026/10/13 21:50:32

最小二乘法系统辨识:MATLAB实现、阶次选择与避坑指南

简介:这份MATLAB程序包面向自动化、控制工程及信号处理方向的学习者与研究人员,用于系统辨识课程的实验与算法验证。包内共7个文件,全部为.m脚本,压缩包约7KB,涵盖普通最小二乘、递归最小二乘、扩展递归最小二乘、广义…

作者头像 李华
网站建设 2026/10/13 21:48:54

CNN卷积层与池化层原理详解:从参数计算到PyTorch实战

1. 卷积层与池化层的核心工作原理解读1.1 卷积层到底在做什么:一个生活视角在正式敲代码之前,我想先和你一起把卷积层这件事彻底想明白。回到系列前几篇,我们已经解决了"怎么用线性层激活函数搭出一个能跑的网络"的问题&#xff0c…

作者头像 李华