Python带你找回童年的万花尺
off999 2025-05-16 15:34 25 浏览 0 评论
还记得小时候的万花尺吧?这么画:
一点也不费脑筋,就可以出来这么多丰富多彩的复杂几何图形。
具体而言,可以用万花尺玩具(如图2-1所示)来绘制数学曲线。这种玩具由两个不同尺寸的塑料齿轮组成,一大一小。小的齿轮有几个孔。把钢笔或铅笔放入一个孔,然后在较大齿轮(内部有齿)内旋转里面的小齿轮,保持笔与外轮接触,可以画出无数复杂而奇妙的对称图案。
现在,在电脑里,用Python也可以这么玩了,让我们看看Python的万花尺效果吧。(不用急,程序在后哦)
$ python spiro.py
默认情况下,spiro.py程序绘制随机螺线,如图2-5所示。按S键保存绘制。
再次运行程序,这次在命令行传入参数,画出特定的螺线。
$ python spiro.py --sparams 300 100 0.9
图2-6展示了输出结果。如你所见,这段代码根据用户指定的参数绘制了一条螺线,图2-5和它不同,展示了几个随机螺线的动画。
这么神奇又好玩的万花尺,在Python里怎么玩呢?
不要走开,让我们继续下面的Python之旅。
在这个项目中,我们将用Python来创建动画,像万花尺一样绘制曲线。我们的spiro.py程序将用Python和参数方程来描述程序的万花尺齿轮的运动,并绘制曲线(我称之为螺线)。我们可以将完成的画图保存为PNG图像文件,并用命令行选项来指定参数或生成随机螺线。
在这个项目中,我们将学习如何在计算机上绘制螺线。还将学习以下几点:
- 用turtle模块创建图形;
- 使用参数方程;
- 利用数学方程来生成曲线;
- 用线段来画曲线;
- 用定时器来生成图形动画;
- 将图形保存为图像文件。
参数方程
在本节中,你将看到用参数方程来画圆的简单例子。参数方程将曲线上点的坐标表示为一个变量的函数,该变量称为参数。参数方程让绘制曲线变得容易,因为只要将参数代入方程就能产生曲线。
注意
如果你现在不想学习这部分数学知识,可以跳到下一部分,讨论针对万花尺项目的方程。
我们开始考虑用半径 r 来描述一个圆的方程,圆心位于二维平面的原点。 x 、 y 坐标满足该方程的所有点构成了圆。
现在,请考虑下面的方程:
x = r cos( θ )
y = r sin( θ )
这些方程是圆的参数表示,其中角 θ 是参数。这些方程中(X,Y)的任何值,都满足前面描述的圆的方程,X 2 + Y 2 = R 2 。如果让 θ 从0变到2π,可以用这些方程来计算圆上对应的 x 和 y 坐标。图2-2展示了这种方案。
记住,这两个方程适用于圆心在坐标系原点的圆。将圆心转换到点( a , b ),就可以将圆置于 xy 平面的任何位置。所以更一般的参数方程就变成 x = a + r cos( θ )和 y = b + r cos( θ )。现在,让我们来看看描述螺线的方程。
万花尺方程
图2-3展示了类似万花尺运动的数学模型。该模型没有齿轮,因为玩具中的齿轮只是为了防止打滑,而在这里不必担心打滑。
在图2-3中,C是较小的圆的圆心,P是笔尖。较大的圆半径为 R ,较小的圆半径为 r 。半径之比表示如下:
将线段PC与小圆半径 r 之比作为变量l(l = PC / r ),它决定了笔尖离小圆圆心有多远。然后,组合这些变量来表示P的运动,得到如下的参数方程:
注意
这些曲线称为内旋轮线和外旋轮线。虽然方程可能看起来有点吓人,但推导是非常简单的。如果你想探索其中的数学,请参见维基百科。
图2-4展示了如何用这些方程,基于参数的变化,产生一条曲线。通过改变参数 R 、 r 和 l ,可以产生变化无穷的迷人曲线。
将曲线绘制为一系列点之间的线段。如果这些点足够接近,图看起来就像平滑的曲线。真正玩过万花尺就知道,这取决于使用的参数,万花尺可能需要许多转数来完成。要确定何时停止绘图,就要利用万花尺的周期性(即万花尺图案多久开始重复),研究内外圆的半径之比:
分子分母除以它们的最大公约数(GCD),化简该分数,分子就告诉我们需要多少圈才能完成曲线。例如,在图2-4中,( r , R )的GCD是5。
下面是该分数化简后的形式:
这告诉我们,13圈后,曲线将开始重复。44告诉我们小圆围绕其中心旋转的圈数,它提示了曲线的形状。在图2-4中数一下,会看到图形中花瓣或叶的数目恰好是44!
一旦用简化形式表示了半径比 r / R ,画出螺线的参数 θ 范围就是[0,2πr]。这告诉我们何时停止绘制特定的螺线。不知道该角度的结束范围,就会循环不止,不必要地重复该曲线。
海龟画图
我们可以用Python的turtle模块来创建图案。这是一个简单的绘图程序,模型是一只海龟拖着尾巴穿过沙滩,留下图案。turtle模块包括了一些方法,用于设置笔(海龟的尾巴)的位置和颜色,以及其他有用的绘图函数。如你所见,只要少量绘图函数,就可以创建漂亮的螺线。
例如,这个程序用turtle画圆。输入以下代码,保存为drawcircle.py,在Python中运行它:
import math ① import turtle # draw the circle using turtle def drawCircleTurtle(x, y, r): # move to the start of circle ② turtle.up() ③ turtle.setpos(x + r, y) ④ turtle.down() # draw the circle ⑤ for i in range(0, 365, 5): ⑥ a = math.radians(i) ⑦ turtle.setpos(x + r*math.cos(a), y + r*math.sin(a)) ⑧ drawCircleTurtle(100, 100, 50) ⑨ turtle.mainloop()
在①行,从导入turtle模块开始。接下来,定义drawCircleTurtle()方法,它在②行调用up()。这告诉Python提笔。换句话说,让笔离开虚拟的纸,这样移动海龟也不会画图。开始绘图之前,先定位海龟。
在③行,将海龟的位置设置为横轴上的第一个点:(x + r, y),其中(x,y)是该圆的圆心。现在准备好画图了,所以在④行调用down()。在⑤行,利用range(0, 365, 5)开始循环,以5为步长递增变量i,从0到360,变量i是角度参数,将传入圆的参数方程,但首先在⑥行将它从度转为弧度(大多数计算机程序的角度计算需要弧度)。
在⑦行,利用前面讨论过的参数方程计算圆的坐标,并设置相应的海龟位置,这样就从海龟上一个位置画线到新计算的位置(从技术上讲,产生的是N边多边形,但因为用了很小的角度,N将非常大,多边形看起来像一个圆)。
在⑧行,调用drawCircleTurtle()来画圆,在⑨行,调用mainloop(),它保持tkinter窗口打开,让你可以欣赏你画的圆(Tkinter是Python默认的GUI库)。
现在,我们准备好画一些螺线了!
所需模块
我们将利用下面的模块创建螺线:
- turtle模块用于绘图;
- pillow,这是Python图像库(PIL)的一个分支,用于保存螺线图像。
代码
首先,定义类Sipro,来绘制这些曲线。我们会用这个类一次画一条曲线(利用draw()方法),并利用一个定时器和update()方法,产生一组随机螺线的动画。为了绘制Spiro对象并产生动画,我们将使用SpiroAnimator类。
要查看完整的项目代码,请直接跳到2.4节。
Spiro构造函数
下面是Spiro构造函数:
# a class that draws a Spirograph class Spiro: # constructor def __init__(self, xc, yc, col, R, r, l): # create the turtle object ① self.t = turtle.Turtle() # set the cursor shape ② self.t.shape('turtle') # set the step in degrees ③ self.step = 5 # set the drawing complete flag ④ self.drawingComplete = False # set the parameters ⑤ self.setparams(xc, yc, col, R, r, l) # initialize the drawing ⑥ self.restart()
在①行,Spiro构造函数创建一个新的turtle对象,这将有助于我们同时绘制多条螺线。在②行,将光标的形状设置为海龟(在
https://docs.python.org/3.3/library/ turtle.html ,你可以在turtle文档中找到其他选项)。在③行,将参数绘图角度的增量设置为5度,在④行,设置了一个标志,将在动画中使用它,它会产生一组螺线。
在⑤和⑥行,调用设置函数,接下来讨论该函数。
设置函数
现在让我们看看getParams()方法,它帮助初始化Spiro对象,如下所示:
# set the parameters def setparams(self, xc, yc, col, R, r, l): # the Spirograph parameters ① self.xc = xc self.yc = yc ② self.R = int(R) self.r = int(r) self.l = l self.col = col # reduce r/R to its smallest form by dividing with the GCD ③ gcdVal = gcd(self.r, self.R) ④ self.nRot = self.r//gcdVal # get ratio of radii self.k = r/float(R) # set the color self.t.color(*col) # store the current angle ⑤ self.a = 0
在①行,保存曲线中心的坐标。然后在②行,将每个圆的半径( R 和 r )转换为整数并保存这些值。在③行,用Python模块fractions内置的gcd()方法来计算半径的GCD。我们将用这些信息来确定曲线的周期性,在④行将它保存为self.nRot。最后,在⑤行,保存当前的角度,我们将用它来创建动画。
restart()方法
接下来,restart()方法重置Spiro对象的绘制参数,让它准备好重画:
# restart the drawing def restart(self): # set the flag ① self.drawingComplete = False # show the turtle ② self.t.showturtle() # go to the first point ③ self.t.up() ④ R, k, l = self.R, self.k, self.l a = 0.0 ⑤ x = R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k)) y = R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k)) ⑥ self.t.setpos(self.xc + x, self.yc + y) ⑦ self.t.down()
这里用了布尔标志drawingComplete,来确定绘图是否已经完成,在①行初始化该标志。绘制多个Spiro对象时,这个标志是有用的,因为它可以追踪某个特定的螺线是否完成。在②行,显示海龟光标,以防它被隐藏。在③行提起笔,这样就可以在⑥行移动到第一个位置而不画线。在④行,使用了一些局部变量,以保持代码紧凑。然后,在⑤行,计算角度a设为0时的 x 和 y 坐标,以获得曲线的起点。最后,在⑦行,我们已完成,并落笔。Setpos()调用将绘制实际的线。
draw()方法
draw()方法用连续的线段绘制该曲线。
# draw the whole thing def draw(self): # draw the rest of the points R, k, l = self.R, self.k, self.l ① for i in range(0, 360*self.nRot + 1, self.step): a = math.radians(i) ② x = R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k)) y = R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k)) self.t.setpos(self.xc + x, self.yc + y) # drawing is now done so hide the turtle cursor ③ self.t.hideturtle()
在①行,迭代遍历参数i的完整范围,它以度表示,是360乘以nRot。在②行,计算参数i的每个值对应的 X 和 Y 坐标。在③行,隐藏光标,因为我们已完成绘制。
创建动画
update()方法展示了一段一段绘制曲线来创建动画时所使用的绘图方法。
# update by one step def update(self): # skip the rest of the steps if done ① if self.drawingComplete: return # increment the angle ② self.a += self.step # draw a step R, k, l = self.R, self.k, self.l # set the angle ③ a = math.radians(self.a) x= self.R*((1-k)*math.cos(a) + l*k*math.cos((1-k)*a/k)) y = self.R*((1-k)*math.sin(a) - l*k*math.sin((1-k)*a/k)) self.t.setpos(self.xc + x, self.yc + y) # if drawing is complete, set the flag ④ if self.a >= 360*self.nRot: self.drawingComplete = True # drawing is now done so hide the turtle cursor self.t.hideturtle()
在①行,update()方法检查drawingComplete标志是否设置。如果没有设置,则继续执行代码其余的部分。在②行,update()增加当前的角度。从③行开始,它计算当前角度对应的(X,Y)位置并将海龟移到那里,在这个过程中画出线段。
讨论万花尺方程时,我提到了曲线的周期性。在一定的角度后,万花尺的图案开始重复。在④行,检查角度是否达这条特定曲线计算的完整范围。如果是这样,就设置drawingComplete标志,因为绘图完成了。最后,隐藏海龟光标,你可以看到自己美丽的创作。
SpiroAnimator类
SpiroAnimator类让我们同时绘制随机的螺线。该类使用一个计时器,每次绘制曲线的一段。这种技术定期更新图像,并允许程序处理事件,如按键、鼠标点击,等等。但是,这种计时器技术需要对绘制代码进行一些调整。
# a class for animating Spirographs class SpiroAnimator: # constructor def __init__(self, N): # set the timer value in milliseconds ① self.deltaT = 10 # get the window dimensions ② self.width = turtle.window_width() self.height = turtle.window_height() # create the Spiro objects ③ self.spiros = [] for i in range(N): # generate random parameters ④ rparams = self.genRandomParams() # set the spiro parameters ⑤ spiro = Spiro(*rparams) self.spiros.append(spiro) # call timer ⑥ turtle.ontimer(self.update, self.deltaT)
在①行,该SpiroAnimator构造函数将DeltaT设置为10,这是以毫秒为单位的时间间隔,将用于定时器。在②行,保存海龟窗口的尺寸。然后在③行创建一个空数组,其中将填入一些Spiro对象。这些封装的万花尺绘制,然后循环N次(N传入给构造函数SpiroAnimator),在⑤行创建一个新的Spiro对象,并将它添加到Spiro对象的列表中。这里的rparams是一个元组,需要传入到Spiro构造函数。但是,构造函数需要一个参数列表,所以用Python的*运算符将元组转换为参数列表。
最后,在⑥行,设置turtle.ontimer()方法每隔DeltaT毫秒调用update()。
请注意,在④行调用了一个辅助方法,名为genRandomParams()。接下来就看看这个方法。
genRandomParams()方法
我们用genRandomParams()方法来生成随机参数,在每个Spiro对象创建时发送给它,来生成各种曲线。
# generate random parameters def genRandomParams(self): width, height = self.width, self.height ① R = random.randint(50, min(width, height)//2) ② r = random.randint(10, 9*R//10) ③ l = random.uniform(0.1, 0.9) ④ xc = random.randint(-width//2, width//2) ⑤ yc = random.randint(-height//2, height//2) ⑥ col = (random.random(), random.random(), random.random()) ⑦ return (xc, yc, col, R, r, l)
为了生成随机数,利用来自Python的random模块的两个方法:randint(),它返回指定范围内的随机整数,以及uniform(),它对浮点数做同样的事。在①行,将R设置为50至窗口短边一半长度的随机整数,在②行,将r设置为R的10%至90%之间。
然后,在③行,将l设置为0.1至0.9之间的随机小数。在④和⑤行,在屏幕边界内随机选择 x 和 y 坐标,选择屏幕上的一个随机点作为螺线的中心。在⑥行随机设置为红、绿和蓝颜色的成分,为曲线指定随机的颜色。最后,在⑦行,所有计算的参数作为一个元组返回。
重新启动程序
我们将用另一个restart()方法来重新启动程序。
# restart spiro drawing def restart(self): for spiro in self.spiros: # clear spiro.clear() # generate random parameters rparams = self.genRandomParams() # set the spiro parameters spiro.setparams(*rparams) # restart drawing spiro.restart()
它遍历所有的Spiro对象,清除以前绘制的每条螺线,分配新的螺线参数,然后重新启动程序。
update()方法
下面的代码展示了SproAnimator中的update()方法,它由定时器调用,以动画的形式更新所有的Spiro对象:
def update(self): # update all spiros ① nComplete = 0 for spiro in self.spiros: # update ② spiro.update() # count completed spiros ③ if spiro.drawingComplete: nComplete += 1 # restart if all spiros are complete ④ if nComplete == len(self.spiros): self.restart() # call the timer ⑤ turtle.ontimer(self.update, self.deltaT)
update()方法使用一个计数器nComplete来记录已画的Spiro对象的数目。在①行初始化后,它遍历Spiro对象的列表,在②行更新它们,如果一个Spiro完成,就在③行将计数器加1。
在循环外的④行,检查计数器,看看是否所有对象都已画完。如果已画完,调用restart()方法重新开始新的螺线动画。在⑤行restart()的末尾,调用计时器方法,它在DeltaT毫秒后再次调用update()。
显示或隐藏光标
最后,使用下面的方法来打开或关闭海龟光标。这可以让绘图更快。
# toggle turtle cursor on and off def toggleTurtles(self): for spiro in self.spiros: if spiro.t.isvisible(): spiro.t.hideturtle() else: spiro.t.showturtle()
保存曲线
使用saveDrawing()方法,将绘制保存为PNG图像文件。
# save drawings as PNG files def saveDrawing(): # hide the turtle cursor ① turtle.hideturtle() # generate unique filenames ② dateStr = (datetime.now()).strftime("%d%b%Y-%H%M%S") fileName = 'spiro-' + dateStr print('saving drawing to %s.eps/png' % fileName) # get the tkinter canvas ③ canvas = turtle.getcanvas() # save the drawing as a postscipt image ④ canvas.postscript(file = fileName + '.eps') # use the Pillow module to convert the postscript image file to PNG ⑤ img = Image.open(fileName + '.eps') ⑥ img.save(fileName + '.png', 'png') # show the turtle cursor ⑦ turtle.showturtle()
在①行,隐藏海龟光标,这样就不会在最后的图形中看到它。然后,在②行,使用datetime(),利用当前时间和日期(以“日—月—年—时—分—秒”的格式),以生成图像文件的唯一名称。将这个字符串加在spiro-后面,生成文件名。
turtle程序采用tkinter创建的用户界面(UI)窗口,在③和④行,利用tkinter的canvas对象,将窗口保存为嵌入式PostScript(EPS)文件格式。由于EPS是矢量格式,你可以用高分辨率打印它,但PNG用途更广,所以在⑤行用Pillow打开EPS文件,并在⑥行将它保存为PNG文件。最后,在⑦行,取消隐藏海龟光标。
解析命令行参数和初始化
像第1章中一样,在main()方法中用argparse来解析传入程序的命令行选项。
① parser = argparse.ArgumentParser(description=descStr) # add expected arguments ② parser.add_argument('--sparams', nargs=3, dest='sparams', required=False, help="The three arguments in sparams: R, r, l.") # parse args ③ args = parser.parse_args()
在①行,创建参数解析器对象,在②行,向解析器添加--sparams可选参数。在③行,调用函数进行实际的解析。
接下来,代码设置了一些turtle参数。
# set the width of the drawing window to 80 percent of the screen width ① turtle.setup(width=0.8) # set the cursor shape to turtle ② turtle.shape('turtle') # set the title to Spirographs! ③ turtle.title("Spirographs!") # add the key handler to save our drawings ④ turtle.onkey(saveDrawing, "s") # start listening ⑤ turtle.listen() # hide the main turtle cursor ⑥ turtle.hideturtle()
在①行,用setup()将绘图窗口的宽度设置为80%的屏幕宽度(你也可以给setup指定高度和原点参数)。在②行,设置光标形状为海龟,在③行,设置程序窗口的标题为Spirographs!,在④行,利用onkey()和saveDrawing,在按下S时保存图画。然后,在⑤行,调用listen()让窗口监听用户事件。最后,在⑥行,隐藏海龟光标。
命令行参数解析后,代码的其余部分进行如下:
# check for any arguments sent to --sparams and draw the Spirograph ① if args.sparams: ② params = [float(x) for x in args.sparams] # draw the Spirograph with the given parameters col = (0.0, 0.0, 0.0) ③ spiro = Spiro(0, 0, col, *params) ④ spiro.draw() else: # create the animator object ⑤ spiroAnim = SpiroAnimator(4) # add a key handler to toggle the turtle cursor ⑥ turtle.onkey(spiroAnim.toggleTurtles, "t") # add a key handler to restart the animation ⑦ turtle.onkey(spiroAnim.restart, "space") # start the turtle main loop ⑧ turtle.mainloop()
在①行,首先检查是否有参数赋给--sparams。如果有,就从字符串中提取它们,用“列表解析”将它们转换成浮点数②(列表解析是一种Python结构,让你以紧凑而强大的方式创建一个列表,例如,a = [2*x for x in range(1, 5)]创建前4个偶数的列表)。
在③行,利用任何提取的参数来构造Spiro对象(利用Python的*运算符,它将列表转换为参数)。然后,在④行,调用draw(),绘制螺线。
现在,如果命令行上没有指定参数,就进入随机模式。在⑤行,创建一个SpiroAnimator对象,向它传入参数4,告诉它创建4幅图画。在⑥行,利用onkey()来捕捉按键T,这样就可以用它来切换海龟光标(toggleTurtles),在⑦行,处理空格键(space),这样就可以用它在任何时候重新启动动画。最后,在⑧行,调用mainloop()告诉tkinter窗口保持打开,监听事件。
完整代码
可以从公众号pythondada输入万花尺索取完成代码。
相关推荐
- pip的使用及配置_pip怎么配置
-
要使用python必须要学会使用pip,pip的全称:packageinstallerforpython,也就是Python包管理工具,主要是对python的第三方库进行安装、更新、卸载等操作,...
- Anaconda下安装pytorch_anaconda下安装tensorflow
-
之前的文章介绍了tensorflow-gpu的安装方法,也介绍了许多基本的工具与使用方法,具体可以看Ubuntu快速安装tensorflow2.4的gpu版本。pytorch也是一个十分流行的机器学...
- Centos 7 64位安装 python3的教程
-
wgethttps://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz#下载指定版本软件安装包tar-xzfPython-3.10.1...
- 如何安装 pip 管理工具_pip安装详细步骤
-
如何安装pip管理工具方法一:yum方式安装Centos安装python3和python3-devel开发包>#yuminstallgcclibffi-develpy...
- Python入门——从开发环境搭建到hello world
-
一、Python解释器安装1、在windows下步骤1、下载安装包https://www.python.org/downloads/打开后选择【Downloads】->【Windows】小编是一...
- 生产环境中使用的十大 Python 设计模式
-
在软件开发的浩瀚世界中,设计模式如同指引方向的灯塔,为我们构建稳定、高效且易于维护的系统提供了经过验证的解决方案。对于Python开发者而言,理解和掌握这些模式,更是提升代码质量、加速开发进程的关...
- 如何创建和管理Python虚拟环境_python怎么创建虚拟环境
-
在Python开发中,虚拟环境是隔离项目依赖的关键工具。下面介绍创建和管理Python虚拟环境的主流方法。一、内置工具:venv(Python3.3+推荐)venv是Python标准...
- 初学者入门Python的第一步——环境搭建
-
Python如今成为零基础编程爱好者的首选学习语言,这和Python语言自身的强大功能和简单易学是分不开的。今天千锋武汉Python培训小编将带领Python零基础的初学者完成入门的第一步——环境搭建...
- 全网最简我的世界Minecraft搭建Python编程环境
-
这篇文章将给大家介绍一种在我的世界minecraft里搭建Python编程开发环境的操作方法。目前看起来应该是全网最简单的方法。搭建完成后,马上就可以利用python代码在我的世界自动创建很多有意思的...
- Python开发中的虚拟环境管理_python3虚拟环境
-
Python开发中,虚拟环境管理帮助隔离项目依赖,避免不同项目之间的依赖冲突。虚拟环境的作用隔离依赖:不同项目可能需要不同版本的库,虚拟环境可以为每个项目创建独立的环境。避免全局污染:全局安装的库可...
- Python内置zipfile模块:操作 ZIP 归档文件详解
-
一、知识导图二、知识讲解(一)zipfile模块概述zipfile模块是Python内置的用于操作ZIP归档文件的模块。它提供了创建、读取、写入、添加及列出ZIP文件的功能。(二)ZipFile类1....
- Python内置模块pydoc :文档生成器和在线帮助系统详解
-
一、引言在Python开发中,良好的文档是提高代码可读性和可维护性的关键。pydoc是Python自带的一个强大的文档生成器和在线帮助系统,它可以根据Python模块自动生成文档,并支持多种输出格式...
- Python sys模块使用教程_python system模块
-
1.知识导图2.sys模块概述2.1模块定义与作用sys模块是Python标准库中的一个内置模块,提供了与Python解释器及其环境交互的接口。它包含了许多与系统相关的变量和函数,可以用来控制P...
- Python Logging 模块完全解读_python logging详解
-
私信我,回复:学习,获取免费学习资源包。Python中的logging模块可以让你跟踪代码运行时的事件,当程序崩溃时可以查看日志并且发现是什么引发了错误。Log信息有内置的层级——调试(deb...
- 软件测试|Python logging模块怎么使用,你会了吗?
-
Pythonlogging模块使用在开发和维护Python应用程序时,日志记录是一项非常重要的任务。Python提供了内置的logging模块,它可以帮助我们方便地记录应用程序的运行时信息、错误和调...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)