十二、有趣且丰富的迷你项目!
在前一章中,我们深入探讨了 Python 提供的四种预定义数据结构,即列表、集合、元组和字典。我们研究了如何创建、删除、操作它们,等等。最后,我们看了如何在程序中使用它们,以及为什么它们在真实的编程场景中有用。
在这一章中,让我们暂时放下所有的学习,开始创作吧!我们将创建许多迷你项目。你可以通过创建这些迷你项目来温习到目前为止所学的主题。所以,跟我一起编码吧。玩得开心!
专题 12-1:奇数还是偶数
让我们从简单的事情开始这一章。这是任何编程语言中的经典难题。
我们将分两部分完成这个项目。在第一部分中,我们将检查一个给定的数是偶数还是奇数。在第二部分中,我们将从用户那里获得一个数字范围,并打印该范围内的偶数或奇数。
但是在我们开始之前,让我问你一个问题。我们如何决定一个数是奇数还是偶数?嗯,任何被 2 除尽的数都是偶数,对吗?除以 2 得出 1 的数是奇数。
这个概念很简单。您还记得模数运算符吗?它返回除法运算的余数。
当你把一个偶数除以 2 时,你会得到什么?0
当你把一个奇数除以 2 时,你会得到什么?一
就这样!所以,如果这个数和 2 的模返回 0,我们就得到一个偶数。如果没有,我们得到一个奇数。
现在,我们可以创建我们的程序了吗?
第一部分-你的号码是奇数还是偶数?
-
获取输入并将其转换为整数。
-
然后,检查模量。如果是 0,就是偶数;否则就是奇数。
num = input('Enter a number: ')
num = int(num)
- 让我们运行程序。我的输入是 45。
if((num % 2) == 0):
print('{} is an Even number'.format(num))
else:
print('{} is an Odd number'.format(num))
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\dataStructures.py
Enter a number: 45
45 is an Odd number
第二部分-打印一个范围内的奇数或偶数
现在,对于第二个程序,让我们从用户那里获得一个范围,以及他们是否希望在该范围内打印偶数或奇数,并打印相同的数字。
-
获取范围并将它们转换为整数。也获得了“选择权”。
start = input('Enter the start of the range: ') end = input('Enter the end of the range: ') start = int(start) end = int(end) choice = input('Even or Odd? Enter e or o: ')
-
在我们循环遍历这个范围之前,让我们检查一下它是否正确。“开始”值应该小于“结束”值。
-
如果是,让我们创建一个遍历整个范围的 for 循环。如果选择为奇数,则仅在模数的结果为 1 时打印。如果选择偶数,则仅当模数的结果为 0 时打印。如果两者都不是,他们给出了一个无效的选择,并打印一条错误消息。
for i in range(start,end+1): if(choice == 'o' or choice == 'O'): if((i % 2) == 1): print(i) elif(choice == 'e' or choice == 'E'): if((i % 2) == 0): print(i) else: print('Enter a valid choice and try again')
-
最后,也为该范围打印一条错误消息。
else: print('Enter a valid range')
-
让我们运行这个程序。我的范围是 1 到 10,我想打印这个范围内的奇数。
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\dataStructures.py Enter the start of the range: 1 Enter the end of the range: 10 Even or Odd? Enter e or o: O 1 3 5 7 9
if(start < end):
太好了。
项目 12-2:你妈妈给的小费够吗?
在这个项目中,我们将创建一个小费计算器,输入总账单和他们的妈妈给服务员的小费。计算他们的妈妈给的小费的百分比,如果是 10-15%就说好,如果是 15-20%就说好,如果是 20%以上就说好。如果少于 10%,就说他们的妈妈给的小费不够。
让我们创造它,好吗?
-
获取账单金额和小费,并将它们转换为整数。
bill = input('What was your bill? ') tip = input('How much did you tip? ') bill = int(bill) tip = int(tip)
-
让我们计算一下小费的百分比。为此,将小费乘以 100,然后除以账单金额。这只是你计算百分比的反向操作。让我们将百分比(由于除法运算,它将是一个浮点数)转换为整数。
percent = (tip * 100) / bill percent = int(percent)
-
现在,让我们使用 if elif else 打印出正确的消息。简单!
if((percent >= 10) and (percent <= 15)): print('{}%. You tipped Okay'.format(percent)) elif((percent >= 15) and (percent <= 20)): print('{}%. That was a good tip!'.format(percent)) elif(percent >= 20): print('{}%. Wow, great tip! :)'.format(percent)) else: print("{}%. You didn't tip enough :(".format(percent))
运行这个程序,你会得到这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\dataStructures.py
What was your bill? 400
How much did you tip? 45
11%. You tipped Okay
作品!
项目 12-3:画一棵圣诞树
你知道你可以用基本的 Python 语法画一棵圣诞树吗?没有包或模块,只有 Python。我们试试好吗?
所以基本上,给定树的高度,我想让我的程序画一棵这个高度的树。很简单,对吧?
正如你可能猜到的,我们需要循环来做这件事,树看起来就像图 12-1 。
图 12-1
5 米高的圣诞树
这个程序是如何工作的?
因此,我们需要一个循环遍历树的每一行,另一个循环遍历树的高度。这称为嵌套循环。在这个嵌套循环中,遍历树的高度的循环是外部循环,对于外部循环的每次迭代,我们将使用内部循环来绘制相关的行。
我们开始吧!
每当我们试图画谜题或任何类型的问题时,最好是写一个算法来帮助我们更好地编写程序。在这种情况下,我将使用前面的树来逆向工程我的算法。你想看看怎么样吗?
算法:
-
在图 12-1 中,树的高度为 5。所以,我们需要五排叶子和一个树桩在末端(在树的中间)。
-
第一行有 1 颗星,第二行有 1 + 2 (3)颗星,第三行有 3 + 2 (5)颗星,依此类推,直到最后。
-
如果你在画出第一颗星星(第一行)之前数空格数,是四,也就是树的高度减一。对于第二行,空格数为 3,随后每减少一行。
-
树桩又是四格之后画的,所以和我们第一排一样。我们需要一个单独的 for 循环来绘制树桩,因为它不是树的给定高度的一部分。
好了,现在我们已经有了一个算法,让我们开始吧!
让我们创建我们的程序吧!
-
让我们先获得树的高度,然后将字符串转换为整数。
n = input("What's the height of your tree? ") n = int(n)
-
接下来,让我们分配变量。我将创建一个变量 sp,它将表示空格的数量。它将从 n-1 开始。我可以减少循环内部的值。
同样,我将创建另一个变星,从 1 开始。
-
现在,让我们画我们的树吧!主 for 循环将遍历树的整个高度(0 到 n–1,所以范围是 0,n)
#draw the tree for i in range(0,n):
-
在主外部 for 循环中,我们需要两个内部 for 循环,一个用来画空格,一个用来画星星。
We need to loop from 0 to sp, and for every iteration of the loop, print a single space. But here’s the catch. Print statements end at new lines, so if you want to be on the same line, you need to use an attribute called end and give it an empty string as its value. This will make sure that the next space is drawn right next to the first space.
#draw spaces for j in range(0,sp): #By default, a print function ends with a newline. Use the end='' to make it end with an empty string instead, so we can draw the star next print(' ',end='')
-
现在,让我们画出我们的星星。为此,我们需要遍历范围 0,star–1。再次使用 end= ’ '以确保它们绘制在同一条线上。
for k in range(0,star): print('*',end='')
-
我们现在已经完成了内部 for 循环。在开始外部 for 循环的下一次迭代之前(我们的树的下一行),让我们更改变量的值。让我们将 star 增加 2,将 sp 减少 1。让我们将一个空的 print()放在最后,因为我们已经完成了这一行,下一行需要一个新的行。
star += 2 sp -= 1 print() #so there's a new line
-
那棵树就这样了!现在,关于树桩。做你在第一排做的。从 0 到 n–2(范围 0,n–1)运行一个 for 循环,并打印一个 end= ’ '的空格。一旦循环完成,打印一个星星,我们就完成了!
#draw the stump for i in range(0,n-1): print(' ',end='') print('*')
sp = n-1
star = 1
喔!这花了一些时间。我们运行这个程序好吗?
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/mini_projects.py
What's the height of your tree? 10
按回车键,你会得到这个(图 12-2 )。
图 12-2
10 米高的圣诞树
耶!有效!
项目 12-4:螺旋!
在这个项目中,我们将制作不同种类的随机彩色螺旋。会很有趣的!
方形螺旋
-
首先,让我们创建一个方形螺旋。因为我们需要随机选择颜色,我们需要导入 turtle 和 random 模块。
#Square spiral import turtle, random
-
让我们先设置乌龟屏幕,并将笔的大小设置为 5,速度设置为 0。
s = turtle.getscreen() t = turtle.Turtle() t.pensize(5) t.speed(0)
-
因为这将是一个方形螺旋,我将长度设为 4。你会明白为什么。
-
让我们也创建一个颜色列表,我们将在我们的循环中随机选择。
colors = ['Red', 'Brown', 'Green', 'Blue', 'Orange', 'Yellow', 'Magenta', 'Violet', 'Pink']
-
现在,让我们创建我们的循环,并使它从 1 到 149(因此范围为 1–150)。经过反复试验,我选择了这个数字。然后,我将使用 random.choice 方法,该方法从列表中随机选择项目,并将选择的项目赋给变量“color”。
for x in range(1,150): color = random.choice(colors)
-
将钢笔颜色更改为该颜色,并使钢笔向前移动“长度”并向右移动 90 度。然后,将长度的当前值加上 4,这样在下一次迭代中,笔将向前移动 4 个点。这不断重复,因此,我们已经创建了一个螺旋,它的大小不断增加(因为长度值的增加,也因为我们在每条线被画出后都旋转了 90 度)。
t.pencolor(color) t.forward(length) t.right(90) length += 4
-
最后,把乌龟藏起来。
t.hideturtle() turtle.hideturtle()
length = 4
运行前面的代码,你会得到这个(图 12-3 )。
图 12-3
方形螺旋
改变范围和长度的初始值(和增量),你会得到不同大小的方形螺旋。试试看!
随机螺旋
既然我们意识到螺旋的形状取决于长度和角度,那么如果我们把角度换成其他角度,比如 80 度,会发生什么呢?当然,我们将创建一个随机形状的螺旋!
这几乎像一个五边形,但不完全像,因为五边形的外角是 72 °,这里我们给了 80°。只是为了表明你可以让你的想象力天马行空,得到令人敬畏的结果!
#Spiral pentagon
import turtle, random
s = turtle.getscreen()
t = turtle.Turtle()
t.pensize(5)
t.speed(0)
length = 4
colors = ['Red', 'Brown', 'Green', 'Blue', 'Orange', 'Yellow', 'Magenta', 'Violet', 'Pink']
for x in range(1,200):
color = random.choice(colors)
t.pencolor(color)
t.forward(length)
t.right(80)
length += 2
t.hideturtle()
turtle.hideturtle()
运行前面的代码,你会得到这个(图 12-4 )。
图 12-4
随机螺旋
三角形螺旋
因为三角形的外角是 120 度,将角度改为 120 度,你就得到一个三角形螺旋!
#Triangular spiral
import turtle, random
s = turtle.getscreen()
t = turtle.Turtle()
t.pensize(5)
t.speed(0)
length = 4
colors = ['Red', 'Brown', 'Green', 'Blue', 'Orange', 'Yellow', 'Magenta', 'Violet', 'Pink']
for x in range(1,120):
color = random.choice(colors)
t.pencolor(color)
t.forward(length)
t.right(-120) #-120 so we get a triangle facing upward
length += 4
t.hideturtle()
turtle.hideturtle()
运行前面的代码,你会得到这个(图 12-5 )。
图 12-5
三角形螺旋
星形螺旋
因为星星的外角是 144 度,给你的角度 144 度,你就得到一个星形螺旋!
#Star spiral
import turtle, random
s = turtle.getscreen()
t = turtle.Turtle()
t.pensize(5)
t.speed(0)
length = 4
colors = ['Red', 'Brown', 'Green', 'Blue', 'Orange', 'Yellow', 'Magenta', 'Violet', 'Pink']
for x in range(1,130):
color = random.choice(colors)
t.pencolor(color)
t.forward(length)
t.right(144)
length += 4
t.hideturtle()
turtle.hideturtle()
运行前面的代码,你会得到这个(图 12-6 )。
图 12-6
星形螺旋
圆形螺旋
圆形螺旋会和其他的有点不同。我们的长度仍然是 4,但是我们一次只向前移动一点,得到一个圆形,在这种情况下我把角度设为 20。您可以改变角度,使您的螺旋紧密结合,并进一步分开。
#Circular spiral
import turtle, random
s = turtle.getscreen()
t = turtle.Turtle()
t.pensize(5)
t.speed(0)
length = 4
colors = ['Red', 'Brown', 'Green', 'Blue']
for x in range(1,100):
color = random.choice(colors)
t.pencolor(color)
t.forward(length)
t.right(20)
length += 1
t.hideturtle()
turtle.hideturtle()
运行前面的代码,你会得到这个(图 12-7 )。
图 12-7
圆形螺旋
项目 12-5:复杂的曼荼罗——完全自动化
在这个项目中,让我们用 for 循环画一个复杂的曼荼罗。这也是随机着色的。看起来会很壮观!
-
先导入随机和海龟模块,设置好海龟屏和笔。接下来,让我们改变笔的大小为 5,速度为 0。
#Mandala import turtle, random s = turtle.getscreen() t = turtle.Turtle() t.pensize(5) t.speed(0)
-
接下来让我们创建一个颜色列表。
-
然后,我们将使我们的循环遍历 1 到 24 (1,25 作为范围)。
colors = ['Red', 'Blue', 'Green']
-
让我们选择我们的随机颜色,并改变笔的颜色。
color = random.choice(colors) t.pencolor(color)
-
现在有趣的部分来了。曼荼罗通常是复杂地画圆,我对吗?所以,让我们为每次迭代画一个 100 点的圆,但是每次稍微移动角度 15 度,所以我们得到一个紧密编织的曼荼罗设计(你会看到)。
t.circle(100) t.right(15) #closely formed mandala
-
最后,把乌龟藏起来。
t.hideturtle() turtle.hideturtle()
for x in range(1,25):
运行前面的代码,你会得到这个(图 12-8 )。
图 12-8
复杂曼陀罗
尝试改变循环的范围,圆的半径,和角度来得到不同类型的曼荼罗。你可以创造数百个这样的设计!
项目 12-6: 乌龟 带圈赛跑
这将是一个有趣的小游戏,展示了 for 循环和 Python 随机包的强大威力。我们还将学习一些我们在turtle
章节中跳过的turtle
方法。兴奋吗?我也是!
所以,概念很简单。我们有三只海龟,我们将在它们之间进行一场比赛。差不多了。当我们完成后,它将看起来像一个实际的,现场比赛发生在我们的屏幕上。我们如何做到这一点?
首先,我们需要我们的玩家,幸运的是, Turtle 让创造“海龟”变得很容易。
-
让我们先导入 turtle 和随机包并设置我们的屏幕。
#Turtles import turtle, random s = turtle.getscreen()
-
现在,对我们的海龟来说,我们不会用通常的方法。我们要用这只乌龟创造三只独立的乌龟。Turtle()命令,命名为红色、蓝色和绿色。乌龟让我们这么做。我们可以随心所欲地创造出任意多的乌龟,并把它们放在我们想要的任何地方,同时让它们画出不同的东西。很酷,你不觉得吗?
-
一旦我们创建了一个玩家(乌龟),我们将改变它的笔的大小为 5,用 color()方法改变“乌龟”的颜色,用 shape()方法改变乌龟的形状为“乌龟”。你马上就会看到这些是如何工作的。
red = turtle.Turtle() red.pensize(5) red.color('Red') red.shape('turtle') blue = turtle.Turtle() blue.pensize(5) blue.color('Blue') blue.shape('turtle') green = turtle.Turtle() green.pensize(5) green.color('Green') green.shape('turtle')
-
最后,让我们隐藏屏幕中央的主海龟。
图 12-9
海龟就位
-
现在,如果你运行这个程序,你不会看到太多。你只能看到绿海龟,因为那是最后画的。要分开看海龟,让我们把它们移到比赛位置。在尝试了很多值之后,我选择了任意值。你可以选择任何你想要的起点。
#Make turtles move to position red.penup() red.goto(-250,150) red.pendown() blue.penup() blue.goto(-250,0) blue.pendown() green.penup() green.goto(-250,-150) green.pendown()
-
现在,让我们运行程序,我们会得到这个(图 12-9 )。
turtle.hideturtle() #hide the main turtle at the center
我们有三个海龟队员,他们已经就位。完美!
-
最后,让我们让他们比赛!创建一个运行 100 次迭代的 for 循环。在每次迭代中,让每只乌龟向前移动一个从 1 到 10 的随机数。这样,我们不知道任何一只海龟会移动多远,这有一种真实世界的比赛感觉。
#Make the turtles move for i in range(100): red.forward(random.randint(1,10)) blue.forward(random.randint(1,10)) green.forward(random.randint(1,10))
差不多就是这样。如果你现在运行程序,你会看到三条不同颜色的线在屏幕上以不同的速度移动,停在不同的点上。这就是了。你的种族(图 12-10 )!
图 12-10
乌龟赛跑
这就是我们的迷你项目!希望你在创造它们的时候很开心。
摘要
在这一章中,我们看了六个不同的有趣的迷你项目。在创建丰富多彩的迷你项目时,我们重温了在前面章节中学到的概念。我们还学习了创建算法来解决编程中的问题和难题。
在下一章,让我们学习如何用函数实现真正的自动化,如何为我们的用户定义函数获取参数,如何用函数节省时间和大量代码行,等等。
十三、功能自动化
在前一章中,我们暂停了所有的学习并创建了更多有趣的迷你项目。现在我们精力充沛了,让我们继续学习几个章节,好吗?
在这一章中,我们将会看到一个非常有趣的概念。我们已经介绍了 Python 中使用循环的自动化,但是在这一章,让我们看看真正的函数自动化。它像魔法一样有效。你会明白的。
真正的自动化
为什么我这么叫它?我们已经看到了循环,它们自己完成了大量的自动化工作。我们只用了几行代码就创建了完整的形状,对吗?那么,我们为什么需要函数呢?
如果你需要重复密码呢?例如,让我们带回我们在循环章节中写的代码。还记得我们如何创建一个程序,它根据我们给它的输入创建一个形状吗?我们不得不多次运行这个程序来绘制不同的形状。如果我想从程序的同一次运行中绘制不同的形状呢?如果我想给出多个输入,那么我的程序一个接一个地绘制每个形状,同时擦除前一个形状,该怎么办?你会怎么做?
你可能需要多次编写相同的代码,用不同的角度和边输入,对吗?所以,如果你想画五个形状,你需要五个循环,一个接一个,每个循环之间有一个 clear()方法。那太长了!如果我们也能缩短它呢?
有了函数,你当然可以!你可以用一个叫做“函数”的东西来创建你的“for 循环”。到目前为止,我们已经使用了很多函数。只是,我们称它们为预定义方法,因为它们已经用 Python 创建了。但是现在,您可以创建自己的函数。多令人兴奋啊。你已经成为一个如此有经验的程序员,你现在可以创建你自己的函数,调用它们,发送参数,自动化,等等。
既然你的“for 循环”在你的函数中,你可以做一些叫做“调用函数”的事情,每次给不同的值,以确保你的 for 循环每次都画出不同的形状。一会儿我会教你怎么做。
但是现在,让我们学习如何编写一个基本函数。
我们的第一个功能
每个函数都有两个部分。有一个函数定义,它有你想要多次执行的代码。然后是函数调用,这是字面上“调用”函数定义的代码行。它可能会发送参数/值作为函数的输入。
但是首先,让我们创建一个没有参数的函数,这样你就能理解它们是如何工作的。
所以,函数是有定义的,不是吗?到目前为止,我们已经注意到 Python 非常直观。它的语法很有意义。“if”是指英文单词 If;而“while”的意思是某事将持续一段时间,因此是一个循环;等等。类似地,“def”意味着你正在创建一个函数定义。
像往常一样,只需提到“def”,即您正在创建的函数的名称,后跟括号和冒号。然后,在下一行中,在缩进后添加代码行。就这么简单!
让我们创建一个打印“Hello there!”的函数当我们称之为。我们命名我们的函数,这样我们可以在以后调用它们。我们已经调用了许多预定义的函数,比如 len()和 join(),对吗?对于您创建的函数,这个概念是相同的:用户定义的函数。我将把我的函数命名为 greet(),因为这就是它要做的,问候调用它的人。
def greet():
print('Hello there!')
太好了。我们有我们的功能。让我们运行它。
蟋蟀…什么也没发生。☹为什么?!
啊对了,我们还没叫呢!我们如何做到这一点?那么,我们如何调用我们的预定义函数呢?格式是一样的。函数名,后跟括号。就这样!
让我们现在正确地做事情。一个函数定义,然后是一个函数调用,就像它应该的那样。
def greet():
print('Hello there!')
greet()
现在运行这个程序,你会得到这个:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/functions.py
Hello there!
啊哈!我们拿到了。
为什么我们需要函数?
但是函数有什么用呢?我很困惑。是吗?它做我们一直在做的事情,而不需要添加额外的代码来创建和调用函数。
嗯…如果我想问候我的用户五次而不是一次呢?也许小组有五个人?在此之前,我会添加五个打印声明。但是现在,我可以添加五个函数调用,就像这样,函数会被调用,然后“你好!”每次都会被打印出来。酷!
greet()
greet()
greet()
greet()
greet()
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/functions.py
Hello there!
Hello there!
Hello there!
Hello there!
Hello there!
我们拿到了。或者我们有吗?这也有什么用?我们仍然创建了五行代码。无论如何我们都会这么做的。我们既没有节省时间,也没有节省空间。倒霉!
每次做不同的事情!
当你每次调用函数时都给它发送不同的值,你就会明白函数的真正用途了。让我们修改一下 greet()程序,让它在每次调用时都问候一个人。
现在我想让函数每次都用他们的名字问候这个人,我需要让我的函数知道他们的名字是什么,对吗?我该怎么做?也许我的函数可以在被调用的时候接收到它?没错。创建函数时,可以在括号内包含发送的一个或多个参数的名称(可以发送任意数量的参数)。
好了,暂停!参数?争论?哪个是哪个?别担心。其实都是一样的,但是如果你想具体一点,你从函数调用中发出的值叫做参数,你在函数定义中收到的值就是实参。简单吧?一旦我们看了我们的例子,你会更好地理解。
创建(定义)您的功能
让我们看看它是如何工作的:
def greet(name):
print('Hello {}!'.format(name))
看那个!我在括号中收到了参数“name ”,然后在我的 print 语句中使用了它。本质上,这不是一个变量,但它的行为很像变量。您可以随意命名您的参数。一旦我们完成了这个例子,你为什么不把你的参数的名字从" name “改成” n ",看看它是否还能工作?
现在我们已经创建了我们的定义,让我们创建程序的其余部分。让我们创建一个变量名并获得输入。然后,让我们调用 greet()函数,但是这一次使用括号内的参数名称“name”。
name = input("What's your name?")
greet(name)
很好!不要被同一个“名字”迷惑了。我只是让变量的名字和函数接收的参数的名字相同,这样你就不会混淆了。但是参数名称可以是您想要的任何名称,并且您的程序仍然可以正常工作。
运行前面的代码,您将得到以下结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py
What's your name? Susan
Hello Susan!
看那个!有效!
你可以重用你的代码!
现在,我将向你展示函数的真正用途。函数的真正用途在于,你不需要一遍又一遍地重复同样的代码行。
因此,让我们创建一个名为“calculation”的函数来计算它接收到的任意两个数的加、减、除和乘。好吗?
因此,它将接收两个数字,n1 和 n2,作为参数。我将进行计算,并将结果打印成四行:
def calculate(n1,n2):
n1 = int(n1)
n2 = int(n2)
add = n1 + n2
sub = n1 - n2
div = n1 / n2
mul = n1 * n2
print('''Addition: {}
Subtraction: {}
Multiplication: {}
Division: {}
'''. format(add,sub,mul,div))
在前面的代码行中,我接收了两个数字作为参数 n1 和 n2。然后我将它们转换成整数,因为我将使用“input()”方法接收数字,默认情况下这些值是字符串。然后,我完成了计算,最后使用多行字符串引号将所有内容打印出来。
现在到了我正在谈论的部分。既然我们已经创建了 calculate 函数,我们可以随时调用它。如果我们想要计算三次呢?在我们发现函数之前,我们会多次编写相同的代码行,因为没有其他方法来接收不同的输入并用不同的值进行相同的计算。
但是现在,我们有办法了!
calculate(input("Enter the first number"),input("Enter the second number"))
calculate(input("Enter the first number"),input("Enter the second number"))
calculate(input("Enter the first number"),input("Enter the second number"))
我已经创建了三个函数调用,其中每个函数调用都有两个参数,它们只不过是输入语句。
让我们运行这些:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py
Enter the first number 10
Enter the second number 5
Addition: 15
Subtraction: 5
Multiplication: 50
Division: 2.0
Enter the first number 5
Enter the second number 10
Addition: 15
Subtraction: -5
Multiplication: 50
Division: 0.5
Enter the first number 100
Enter the second number 20
Addition: 120
Subtraction: 80
Multiplication: 2000
Division: 5.0
看那个!用同样的几行代码,我能够做三组不同的计算,而不用像我们通常做的那样运行程序三次。
这是函数的真正用法。 真正的自动化!
没有争论?
但是在函数调用中发送参数时要小心。如果您没有发送函数定义所期望的参数数量,那么在运行函数时您将会遇到一个错误。如果您发送的参数数量较少或较多,情况也是如此。
def greet(name):
print('Hello {}!'.format(name))
对于上述功能:
greet()
不带参数的调用将产生以下错误:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py
Traceback (most recent call last):
File "C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py", line 3, in <module>
greet()
TypeError: greet() missing 1 required positional argument: 'name'
函数调用缺少一个必需的参数。
另一方面一个叫两个论点:
greet(name1,name2)
您将收到以下错误:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py
Traceback (most recent call last):
File "C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py", line 3, in <module>
greet(name1,name2)
NameError: name 'name1' is not defined
参数未定义!因此,一定要确保实参的数量与函数定义中的形参数量相匹配。
给个答案
到目前为止,我们只是把东西打印出来。但是如果我们需要一个答案呢?假设我有一个表达式,我使用 add()和 mul()函数来获得数字的加法和乘法结果。但是然后,我想,比如说,把他们都分了。在不知道手术结果的情况下,我怎么能这么做呢?打印结果并不总是足够的,不是吗?
Python 对此也有一个简单的解决方案!只需返回结果。就这么简单。使用“return”语句,返回您的结果,它将在您的函数调用中被接收。然后,您可以将函数调用赋给一个变量并使用其结果,或者将函数调用本身作为一个值使用。
迷茫?别这样,亲爱的。另一个有趣的活动正在进行中,它会让你理解这个概念。
让我首先创建两个函数,加法()和乘法()。它们分别接收参数 n1 和 n2,并执行这两个数的加法和乘法。
def addition(n1,n2):
add = n1 + n2
def multiply(n1,n2):
mul = n1 * n2
但是我不能用这些值,对吗?所以,让我把它们还回去。
def addition(n1,n2):
add = n1 + n2
return add
def multiply(n1,n2):
mul = n1 * n2
return mul
现在,我已经返回了数字相加和相乘的结果。或者,您可以只在 return 语句中执行操作,如下所示:
def addition(n1,n2):
return n1 + n2
def multiply(n1,n2):
return n1 * n2
如果你这样做的话,你可以节省几行代码。只有当你的整个函数只有一行代码时,这才会起作用。
好了,现在我们已经准备好了函数,让我们使用它们吧!
num1 = input("Enter your first number: ")
num1 = int(num1)
num2 = input("Enter your second number: ")
num2 = int(num2)
mul = multiply(num1,num2)
add = addition(num1,num2)
calc = mul /add
print("{} / {} = {}".format(mul,add,calc))
在前面的代码行中,我接收了两个数字作为输入,并将字符串转换为整数。然后,我创建了一个名为“calc”的变量,它将这些数字相乘的结果除以这些数字相加的结果。
我没有在那里执行操作,而是接收了变量 mul 和 add 中的值。从技术上讲,这就是我们所需要的,因为这些函数中的 return 语句会将操作的结果返回给函数调用,然后它们就可以在“calc”操作中使用了。
我们要不要检查一下这个是否能用?
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\functions.py
Enter your first number: 10
Enter your second number: 5
50 / 15 = 3.3333333333333335
没错。有效!为什么不同的操作不尝试相同的呢?想怎么复杂就怎么复杂,享受数学乐趣!
没有争论?怎么办!
有时,您可能不知道要发送什么参数。也许你只是想测试一下功能?但是当函数需要参数时不发送参数会给我们一个错误!我们能做什么?
救援的默认参数!
在定义函数时,您可以为参数指定“默认值”,这样,即使您在调用函数时忘记发送任何参数,它们也能正常工作。你想测试一下吗?
在下面的例子中,我创建了一个 printName 函数,它只打印给定的名字。我调用了这个函数两次,一次有参数,一次没有。让我们看看会发生什么。
def printName(name='Susan'):
print('My name is {}'.format(name))
printName('John')
printName()
Run, and:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
My name is John
My name is Susan
它完全按照我们的预期工作。当我们实际从函数调用中发送参数时,默认参数被忽略。如果我们忘记了,它就被使用了。完美!
争论太多了!
函数还没有停止让您的编程生活变得简单。如果你不知道要发送多少个参数呢?但是你想收到所有的,没有任何错误。
武断的论点会帮助你做到这一点。用*listName 而不是参数名来接收它们,这样就可以像访问列表项一样访问每个参数。让我告诉你怎么做。
假设我想打印我的函数调用发送的数字的总和,但是我不知道我需要增加多少,所以我只是把它们作为一个任意的参数接收。
因为*listName 本质上是一个列表,所以我们可以像在列表中一样循环遍历它。
def addNums(*nums):
sum = 0
for num in nums:
sum += num
return sum
现在让我用我的任意参数调用我的函数。
print(addNums(1,5,3,7,5,8,3))
print(addNums(1,3,5,7,9))
print(addNums(1,2,3,4,5,6,7,8,9))
当我运行这个程序时,我得到了这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
32
25
45
哇,这个特性给了我在程序中做任何我想做的事情如此多的自由!
另一方面,你可以发送一个列表作为参数。那也可以。为什么不试着修改前面的程序来发送和接收一列数字呢?
你试过吗?它看起来像这样吗?
def addNums(nums):
sum = 0
for num in nums:
sum += num
return sum
print(addNums([1,5,3,7,5,8,3]))
print(addNums([1,3,5,7,9]))
print(addNums([1,2,3,4,5,6,7,8,9]))
太好了。
全球与本地
到目前为止,我们已经看到,一旦你创建了一个变量,你不能重新定义它。你可以重新给它赋值,是的,例如:
for i in range(1,10):
print(i,end='')
print()
print(i)
看看前面的程序。我创建了一个变量“I ”,它在同一行中打印从 1 到 9 的数字。在 for 循环完成后,我们打印一个新行和“I”的当前值。
让我们运行这个程序,我们会得到这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
123456789
9
看那个!它是 9,这不是一个错误,因为一旦创建了" I ",即使它是在 for 循环中创建的,它也可以被整个程序访问。
函数中的变量
但是函数就不是这样了。现在让我们在函数中创建相同的内容:
def printNum():
for i in range(1,10):
print(i,end='')
printNum()
print()
print(i)
Run the above, and:
>>>
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
123456789
Traceback (most recent call last):
File "C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py", line 7, in <module>
print(i)
NameError: name 'i' is not defined
看看前面的输出。当函数仍在执行时,一切都很好。它按照我们想要的顺序打印出我们的号码。但是,当我们试图在函数外部打印“I”的当前值时,我们得到一个“未定义”的错误。这怎么可能呢?变量“I”是在函数的 for 循环中定义的,不是吗?
是的,它是,但是它是本地的那个功能,不能在外面使用。因此,在函数内部创建的任何变量都称为局部变量。
**### 返回局部变量
如果你想在函数之外使用它,你需要返回它,就像这样:
def printNum():
for i in range(1,10):
print(i,end='')
return i
i = printNum()
print()
print(i)
现在,运行这个程序,你会得到这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
123456789
9
有效!
全局变量
同样,任何在函数外部创建的变量都被称为 全局 变量,如果你想在函数内部使用它,你需要使用全局关键字,就像这样:
假设我想创建一个全局变量“sum”。每次我发送一个数字列表时,它们都会被添加到 sum 的“当前”值中,所以我们实际上得到的是多个列表的总和。我们如何做到这一点?
我已经创建了一个变量“sum ”,并在程序开始时将其赋值为 0。接下来,让我定义函数。如果我想在函数外部使用相同的“sum”,那么我需要在函数开始时将其称为“全局 sum”(不带引号)。在函数定义的顶部提到全局变量总是一个好习惯。
就这样。程序的其余部分和我们之前写的类似。
sum = 0
def addNums(nums):
global sum
for num in nums:
sum += num
return sum
print(addNums([1,5,3,7,5,8,3]))
print(addNums([1,3,5,7,9]))
print(addNums([1,2,3,4,5,6,7,8,9]))
运行这段代码,您将得到以下结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
32
57
102
sum 的旧值被保留下来,并被添加到后续函数调用中发送的新值中。太好了。
Note
创建顺序和用法 在 Python 中非常重要。在你调用一个函数之前,先定义它。所以, 函数定义 应该总是在函数调用之上,否则会出错。同样,在使用变量之前,先创建它。因此,您的 全局变量 应该在您希望使用它们的函数定义之前创建。
希腊字母的第 11 个
λ是一个匿名函数。它没有名字,可以接受任意数量的参数,但只能有一行代码。听起来很简单,不是吗?当我们有自己的荣耀功能时,为什么我们还需要它呢?
在接下来的章节中,我们将讨论事件。这些事件将让您在单击应用上的按钮、按下鼠标按钮、单击键盘按钮等时调用函数。在这些情况下,Lambdas 是非常需要的,所以让我们现在看看它们(即使现在它们对我们没有太大的用处)。
lambda 的语法非常简单:
variable = lambda arguments: line of code
为什么我们要把 lambda 赋给一个变量?所以我们当然可以称之为!
现在让我们看一个例子:
sum = lambda num1,num2: num1 + num2
现在,我们可以通过调用 sum()来调用 lambda,如下所示:
print(sum(3,5))
print(sum(100,240))
运行前面的代码行,您将得到这样的结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\condition.py
8
340
迷你项目——用 Python 做数学作业
我们会让这个项目变得简单。如果我们使用一个像 Tkinter 这样的包,我们可以使它成为一个合适的应用。但是我们还没有覆盖 Tkinter ,所以我们就在 Shell 中做吧。
我们的计算器将被设计成这样:
-
每种运算都有不同的功能——加、乘、除、减和取模。
-
我们将从用户那里获得信息。我们将从两个数字开始,以及他们选择要进行的手术。
-
然后,我们将打印结果,并询问他们是否想继续使用计算器。
-
如果答案是“Y”或“Y”,那么我们将询问他们是否希望之前的结果作为计算中的一个数字。如果“Y”或“Y”也是,那么我们只需要再输入一个输入,并再次请求他们想要的操作。
-
计算器可以永远这样下去。当用户回答“n”继续时,我们将跳出循环并结束程序。
有趣吗?兴奋地开始了吗?我也是!
-
让我们再次创建执行这些操作的函数。因为函数定义需要在调用之前创建,所以让我们先完成它。
#Addition def add(n1,n2): return n1 + n2 #Subtraction def sub(n1,n2): return n1 - n2 #Multiplication def mul(n1,n2): return n1 * n2 #Division def div(n1,n2): return n1 / n2 #Modulus def mod(n1,n2): return n1 % n2
-
现在,让我们创建一个永不结束的 while 循环,这意味着条件始终为真,直到我们用“break”语句中断循环。
-
在 while 循环中,我们将要求用户输入两个数字作为输入,并像往常一样将字符串转换为整数。
-
然后,我们会要求手术。我们将使用 if…elif…else 语句来调用相关函数并获得结果。
#create a result globally result = 0 #default value repeat = 0 #if the user decided to reuse the result of previous operation, this becomes 1 while(True): #if this is the first/new operation if(repeat == 0): #number1 num1 = input('Your first number: ') num1 = int(num1) #number2 num2 = input('Your second number: ') num2 = int(num2) #If the user asked to use the result of the last operation in this one else: #number2 num2 = input('Your second number: ') num2 = int(num2) #get the operator op = input('''Enter any of the following numbers, that correspond to the given operation: Just the number, not the period. 1\. Addition 2\. Subtraction 3\. Multiplication 4\. Division 5\. Modulus ''') op = int(op) #Call the relevant function if(op == 1): result = add(num1,num2) elif(op == 2): result = sub(num1,num2) elif(op == 3): result = mul(num1,num2) elif(op == 4): result = div(num1,num2) elif(op == 5): result = mod(num1,num2) else: print('You entered an invalid operation. Please run the program again') break #print the result print('Answer: {}'.format(result)) again = input('Do you want to do another operation? Enter Y or N: ') if((again == 'y') or (again == 'Y')): reuse = input('Do you want the result of the current operation to be the first number of the next? Y or N: ') if((reuse == 'y') or (reuse == 'Y')): num1 = result repeat = 1 else: repeat = 0 else: print('Ok bye!') break
迷你项目-自动化形状-下一级
循环是自动化,但是函数应该是真正的自动化,不是吗?为什么我们不看看他们能对我们的自动化形状迷你项目做些什么?
我将创建一个名为 draw_shape()的函数,并将我的代码放入其中。我将在函数中接受两个参数:边数和角度。
如果边数等于 1,我就画一个圆。否则,我要画一个多边形。就这么简单。
对于这个项目,我将使用另一个叫做时间包的包。这样,在绘制下一个形状之前,我可以给出大约 300 毫秒的小延迟,这样用户就可以看到正在发生什么:
-
我们先导入海龟和时间包。
import turtle import time
-
那么让我们建立海龟。我将钢笔颜色设置为红色,填充颜色设置为黄色。
s = turtle.getscreen() t = turtle.Turtle() t.pensize(5) t.color('Red','Yellow')
-
然后,我要定义 draw_shape()函数。在函数开始的时候,我要用时间包的 sleep()方法,基本上让程序停止 0.3 秒(300 毫秒)。然后,我将清除乌龟,这样在我画下一个之前,任何先前的形状都会被删除。
def draw_shape(sides,angle): time.sleep(0.3) t.clear() t.begin_fill() #If sides are greater than 1, then it’s a polygon if sides > 1: for x in range(0,sides): if(x == sides-1): t.home() break t.forward(100) t.right(angle) elif sides == 1: #circle t.circle(100,angle) t.end_fill() t.hideturtle() turtle.hideturtle()
-
我将在不同的函数调用中给出多个值。当您运行这个程序时,您将看到这些形状被连续绘制,中间有 0.3 秒的延迟。
draw_shape(4,90) draw_shape(3,60) draw_shape(5,50) draw_shape(6,60) draw_shape(8,45) draw_shape(1,180) draw_shape(1,360)
您将获得的图像如图 13-1 所示。
图 13-1
自动化形状
整洁!
摘要
在这一章中,我们研究了真正的自动化功能。我们学习了定义函数、调用函数、发送参数使函数动态化、返回值给函数调用、接受任意参数等等。我们也自动化了我们在前面章节中做的一些项目。
在下一章,让我们像专业人士那样进行真实世界的编程!我们将在编程中观察对象并模仿真实世界的场景。**
十四、让我们创造真实世界的对象
在前一章中,我们研究了真正的自动化功能。我们研究了如何使用函数节省时间、空间和代码行,定义函数,调用函数,向函数发送参数,使用默认参数,将值返回到调用语句,以及接受任意参数和列表作为参数。b
在这一章中,让我们看看如何用面向对象编程(OOPs)进行真实世界的编程。我们将会看到类、初始化函数、self、用户定义的属性和方法,以及在我们的类上创建对象。我们还将了解如何访问我们的属性和函数,以及如何更改属性值。
什么是面向对象编程?
Python 中的一切都是对象。它有自己的属性和方法记得吗?现实世界就是这样。就拿我们人类来说吧。我们有属性,比如我们的身高、体重、眼睛颜色、头发颜色等等。同样,我们也有“方法”,比如我们跑步、走路、说话、做事,对吗?
Python 中的一切都反映了我们现实世界中的对象。例如,字符串有长度这样的属性,但是有拆分、大写等方法。人类是一个“群体”,在这个“群体”之下存在着个体的人类,他们有自己的价值观(不同的发色、体重、身高等。).类似地,“字符串”也是一个组,在这个组下,您可以使用自己的属性和方法创建自己的单独字符串。
这就是面向对象编程的核心:真实世界的编程。您可以为项目创建自己的对象,而不是使用预定义的对象及其方法和属性。你看到这里的可能性了吗?现在世界是你的了!
但这是一个庞大的主题,不可能在一章中涵盖所有内容。我也不想让你太困惑。你是来学习 Python 和创建好玩的项目的,我们不用 OOPs(面向对象编程)也能创建本书中的项目。但是我会给你一个 OOPs 的介绍,让你了解它的基本知识。听起来不错?好吧,那我们开始吧!
来证明一下吧!
我刚才说了 Python 里一切都是对象,不是吗?为什么我们不证明一下呢?
让我们从一个整数(一个数)开始,检查它的类型。
num = 10
print(type(num))
运行前面的代码,您将得到这样的结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\oops.py
<class 'int'>
有意思。在下一节中,您将看到类是您在 Python 中创建对象的方式,所以本质上,整数是一个类,保存整数的变量是对象。好吧,但是剩下的数据类型呢?
s = 'Hello'
print(type(s))
b = True
print(type(b))
f = 1.0
print(type(f))
def fName():
pass
print(type(fName))
运行整个程序,你会得到这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\oops.py
<class 'int'>
<class 'str'>
<class 'bool'>
<class 'float'>
<class 'function'>
哇哦!都是课!所以在 Python 中一切确实都是对象。
班级
还记得我之前提到的那些团体吗?如果您想要创建自己的对象,则需要创建一个组,您可以在该组下创建这些对象。“人类”是一个群体,每个人都是一个独立的对象。每个人都有一套我们共有的属性和方法,对吗?
类似地,每组对象都有一组通用的属性和方法,所以让我们为该组创建一个蓝图,并使用自己的一组值分别创建每个对象。
迷茫?不要这样。一会儿就清楚了。
你需要 类 来创建这些蓝图。
为了对真实世界建模,让我们创建一个“Human”类,它具有反映我们人类的属性和方法。
class Human:
sample = 'Sample property value'
就这样!你有你的第一堂课。这不是强制性的,但是在命名你的类的时候,第一个字母要大写,这样当你创建你的对象的时候,你可以更好的区分它们。
好吧。我们有一节课,但是下一节是什么?我们的对象在哪里?你需要创造它们。为什么我们不创建一个“人类 1”对象呢?
human1 = Human()
就这么简单。现在,您可以访问类内部的属性值,如下所示:
print(human1.sample)
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/oops.py
Sample property value
有效!
有自己价值的对象
到目前为止,我们还没有创建基于我们在其上创建的对象来改变其属性值的动态类。
为此,您需要使用一个名为 init()函数的“class”预定义方法。也就是 init 前两个下划线,init 后两个下划线,后跟()。
使用这种方法,您可以在创建对象时发送对象的单个值,以便将它们分配给类的属性。让我们看看如何:
class Human:
def __init__(self,name,age,hair,eye,pet):
self.name = name
self.age = age
self.hair = hair
self.eye = eye
因此,定义 init 函数并接受创建对象时所需的属性。我们的属性将是姓名、年龄、头发(头发颜色)、眼睛(眼睛颜色)和宠物(他们宠物的名字)。
但这还不是全部。一开始就有这个特殊的属性,“自我”。那是什么?你想猜猜吗?什么是自我?你自己?那么它应该是被创造的对象,不是吗?绝对的!
“自我”是被创建的对象,我们正在为该对象创建属性,并为其分配可接受的值。只要遵循变量命名约定,您可以随意命名它。程序员使用“自我”,所以他们知道它是什么。
好了,现在我们已经创建了一个“适当的”类,让我们创建我们的对象。
human1 = Human('Susan',8,'brunette','blue','Barky')
我们的第一个对象是“human1 ”,它将是“human”类的一个对象,我们已经为它发送了一些属性。确保按照 init()函数期望的顺序发送属性,否则可能会出现错误。
你可以像那样创建任意数量的对象。让我们创建另一个。
human2 = Human('Johny',10,'blond','green','Boxer')
到目前为止,这看起来类似于一个常规的函数调用。那为什么要用类呢?
首先,你不需要返回任何东西来访问这些属性。
print(human1.name)
print(human2.eye)
您的对象的名称,后跟一个句点和属性,您就可以开始了。
让我们运行它,我们将得到以下结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/oops.py
Susan
green
没错。我们得到了我们想要的。
操纵你的对象
与函数不同,我们也可以改变对象的属性值。
human2.eye = 'brown'
print('Eye color: {}'.format(human2.eye))
运行所有程序,你会得到这个:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/oops.py
Susan
green
Eye color: brown
看那个。值已更改。
所以,对象是字典和函数的混合体。它们是两个世界中最好的,甚至更多!
就像在字典中一样,您可以使用“del”关键字删除对象的属性,或者只删除整个对象,如下所示:
del human2.eye
del human1
但是不像你的数据结构(列表、字典等等。),不能循环遍历一个对象。☹
对象做事情
当我开始这一章的时候,记得我说过什么吗?对象有属性(就像我们一样),它们做事情或者事情对它们做(就像我们一样)。那么,我们为什么不添加一堆让我们的对象做事情的“方法”呢?
您将创建常规的旧函数,但这次只在类内部创建。
让我们的对象说话,行走,奔跑,好吗?或者只是模拟一样。
class Human:
def __init__(self,name,age,hair,eye,pet):
self.name = name
self.age = age
self.hair = hair
self.eye = eye
def talk(self):
print('{} talking'.format(self.name))
def green(self):
print('Hello there!')
def walk(self):
print("{} is walking".format(self.name))
human1 = Human('Susan',8,'brunette','blue','Barky')
human2 = Human('Johny',10,'blond','green','Boxer')
你注意到我们如何使用自我了吗?从类中访问对象的名字。“自我”是调用函数的对象。每个函数都需要接受“self”来指示调用它的对象,不管是否在函数中使用它的属性值,否则在运行程序时会出错。
让我们现在调用我们的函数,看看我们得到了什么:
human1.talk()
human1.greet()
human2.walk()
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/oops.py
Susan talking
Hello there!
Johny is walking
哇,太好了!
turtle
与对象赛跑
既然我们知道了类是如何工作的,以及如何用它们来创建对象,为什么我们不试着用它们来复制我们的海龟赛跑呢?我相信我们现在可以让代码更简单。
我们将创建一个 turtle 类来创建我们的 Turtle,用一个用户定义的 move()方法随机移动 Turtle(在 1-10 的范围内)。
-
让我们从导入海龟和随机模块以及设置海龟屏幕开始。让我们也把主海龟藏起来。
-
让我们创建一个
turtle
类。初始化函数将接受颜色、x 和 y 来改变海龟的颜色,并将海龟移动到起始位置。
import turtle, random
s = turtle.getscreen()
turtle.hideturtle()
- 那么,我们来定义一下 self.turtle,为什么是 self.turtle 而不是 self?嗯,“self”指的是我们正在创建的对象,所以如果我们想要在该对象上创建一个 turtle,我们需要创建一个包装对象,在我的例子中就是 self.turtle。您可以随意命名它。
class Turtle:
def __init__(self,color,x,y):
这样,原始对象不会被重新分配,我们仍然可以创建一只乌龟。
- 接下来,让我们更改笔的大小、颜色和形状。
self.turtle = turtle.Turtle()
- 最后,让我们把乌龟移动到给定的位置。
self.turtle.pensize(5)
self.turtle.color(color)
self.turtle.shape('turtle')
- 现在我们已经完成了 init()函数,让我们创建一个 move()函数。它只是随机地让乌龟向前移动,就像我们在原程序中做的那样。
self.turtle.penup()
self.turtle.goto(x,y)
self.turtle.pendown()
def move(self):
self.turtle.forward(random.randint(1,10))
我们班到此为止!
-
现在,让我们创建我们的对象。我将创建三个对象,红色、蓝色和绿色,以及它们的相关值。
-
现在,在 0–99(100 次迭代)的范围内,让我们为每一次迭代调用三只乌龟的 move()函数。
red = Turtle('Red',-250,150)
blue = Turtle('Blue',-250,0)
green = Turtle('Green',-250,-150)
for i in range(100):
red.move()
blue.move()
green.move()
就这样!我们的程序工作吗(图 14-1 )?
图 14-1
有阶级的乌龟赛跑
当然了,红队赢了!
摘要
在这一章中,我们看了如何用面向对象编程(OOPs)进行真实世界的编程。我们看了类、初始化函数、self、用户定义的属性和方法,以及在我们的类上创建对象。我们还研究了如何访问我们的属性和函数,以及如何更改属性值。
在下一章中,让我们看看文件,如何创建、打开和修改它们。
十五、Python 和文件
在前一章中,我们学习了如何使用类在 Python 中创建真实世界的对象。我们学习了在 Python 中一切都是对象。然后,我们学习了如何在 Python 中创建类,并使用这些类创建类似的对象,而无需编写太多行代码。
在本章中,我们来看看 Python 中的文件处理。我们将着眼于从 Python 代码内部创建、读取、写入和操作系统中的文件。
为什么是文件?
我能听到你的呻吟。你可能会说,这又是一个无聊的理论话题。别这么快就放弃文件。这是一个很轻松的话题,可以打开太多的可能性去数。
一旦你学会了这一点,现实世界的编程就是你的了。您可以开始将系统中的文件包含在您的程序中,您可以从您的程序中创建它们,读取它们,操作它们,完全删除它们,等等。如果你想在你的笔记本和电脑上创建功能齐全的应用,那么你最好学习文件。
这是一个快速的章节,所以不要太担心,像往常一样,我们将以一个有趣的,这次是简单的迷你项目来结束它。此外,从下一章开始,你将创建所有你想创建的大项目、小项目、应用和游戏,所以更有理由快速完成这一章,你不觉得吗?
打开和读取现有文件
让我们从简单的开始。在对文件做某些事情之前,您需要检索它并将其保存在一个变量中,以便以后可以读取它、写入它等等。
使用“open”方法并在双引号或单引号内指定文件名。您需要指定完整的文件名,包括相关的扩展名,如。py,。txt,等等。
但是,如果文件与脚本存在于同一个文件夹中,那么您可以只提及文件名及其扩展名,就像我在我们的示例中将要做的那样。
我将让我的程序检索 introduction.py 文件,因为它与我为本章创建的 files.py 文件在同一个文件夹中,所以我不需要指定完整的路径。
但是如果我的路径在不同的文件夹中呢?怎么才能拿到?O:
这是一个非常简单的过程。在 Windows 中打开你的文件浏览器,或者在 Mac 中打开它,如图 15-1 所示。
图 15-1
找到您的文件
在我放置箭头的地方单击,也就是在最后一个文件夹名称之后。你会得到路径,像这样(图 15-2 )。
图 15-2
获取您的文件路径
现在,你可以复制路径。但是不能照原样使用。您需要按照以下格式格式化路径和文件名。在前面的示例中,我们试图获取文件“introduction.txt”的路径,该文件位于路径 G:\Python 中。为了在我的程序中使用它,我将把它格式化成这样:
G:\\Python\introduction.txt
然后,我会把整个事情放在引号内,并使用它。就这么简单!
准备好 open()方法后,将其赋给一个变量。为什么呢?一会儿你就知道了!
file = open(' introduction.py')
现在我们已经将文件存储在变量“file”中,我们可以开始操作它了。
你想先做什么?我们要读它吗?打印里面的内容?好吧,就这么办!
你能猜到读取一个文件会怎样吗?也许 Python 有 read()函数我们可以用?是的,你说得对!这正是我们所拥有的。
但是,在使用 read 函数之前,您需要向您的程序指定这正是您要做的事情。因此,当您检索文件时,您需要添加第二个参数,指定您以只读格式检索文件,并且稍后您将读取并可能打印其中的内容。
让我们改变我们的代码行:
file = open(' introduction.py','r')
正如您在前面的代码中看到的,我在引号中包含了第二个参数“r”。这将让我的程序知道,我只是检索文件来读取它,而不是别的。
现在,我们实际上可以读取并打印我们的文件。你想试试吗?
file.read()
让我们运行上面的代码,然后…
蟋蟀…
什么都没发生。😮 为什么?!你让你的程序去读它,它就这样做了。你没让它打印结果吧?你需要对计算机非常清楚。他们需要确切的指示。
因此,让我们打印我们的读取操作:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/file.py
print('Hello there!')
print('My name is Susan Smith.')
print('I am 9 years old.')
print('I love puppies! :)')
看那个!introduction.py 文件中的全部内容(代码)都打印出来了。你注意到什么了吗?尽管该文件包含代码,并且是在 Shell 中打印的,但是这些 print()行并没有被执行。它们就是这样印刷的。
为什么会这样?在这种情况下,您的文件被认为是一个普通的文本文件,代码行是文件中的内容。仅此而已。如果您想要执行前面的代码,您需要以通常的方式进行,而不是通过文件操作打开或读取它。
你可以要求你的程序只打印指定数量的字符,而不是全部。假设我只想打印出前 50 个字符(单个字母、数字、特殊字符和空格),其他什么都不要。然后我要做的就是在括号内指定 50,就像这样:
print(file.read(50))
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/file.py
print('Hello there!')
print('My name is Susan Smith.')
计算前面结果中的字符数,您将得到 50 个,包括作为单独字符的空格和新行。
你为什么不尝试不同的数字,看看你会得到什么?
逐行
如果您不想打印整个文件,也不想计算字符数,该怎么办?如果你只想要第一行呢?然后,您可以使用 readline()方法来读取行。让我们用 readline()代替 read()。
print(file.readline())
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/file.py
print('Hello there!')
耶!只是第一行。
如果我想打印更多的行呢?我可以像在 read()中那样在括号中指定 2 吗?
print(file.readline(2))
运行前面的代码,您将得到这样的结果:
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/file.py
pr
啊,真倒霉。它以为我又要两个字了。我想唯一的办法是指定另一个 readline()。我们试试好吗?
print(file.readline())
print(file.readline())
我们现在有两个 readline()方法。有用吗?
= RESTART: C:/Users/aarthi/AppData/Local/Programs/Python/Python38-32/file.py
print('Hello there!')
print('My name is Susan Smith.')
没错。我们现在有两条线,它们之间有一个巨大的空间,因为它们是用两种不同的印刷品印刷的。
如果你想读取并打印出整个文件,那么就像遍历一个列表一样遍历它。对于循环的每一次迭代,程序将打印文件中的一行。
file = open('introduction.py','r')
for i in file:
print(i)
运行前面的代码,您将得到这样的结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\file.py
print('Hello there!')
print('My name is Susan Smith.')
print('I am 9 years old.')
print('I love puppies! :)')
这是整个文件!
创建新文件
您可以在 open()方法中使用“x”或“w”属性来创建新文件。“w”只是创建一个不存在的文件,但打开一个已存在的文件,而“x”专门用于创建新文件。如果您尝试“创建”一个现有文件,“x”会返回一个错误。
现在让我们创建一个文件 newFile.txt。
file = open('newFile.txt','x')
我们的文件刚刚创建!再次运行程序,你会得到一个错误,因为文件现在已经存在。
操作文件
您可以使用 write 方法向文件中添加。为了做到这一点,你需要打开你想要添加文本的文件,无论是写,“w”,还是附加,“a”,模式。
“写入”模式将覆盖文件中当前的任何文本。追加模式将给定的文本追加到文件的末尾。
我们两个都试试,好吗?
我已经以“写”模式打开了我们在上一节中创建的文件。
file = open('newFile.txt','w')
现在,让我们使用“write”方法向我们的文件添加几行文本,由新行“\n”分隔。
f.write('Hi there!\nThis is a new file.\nWe just added text to it!')
现在,让我们阅读我们的文件,看看我们是否得到同样的结果。
file = open('newFile.txt', 'r')
print(file.read())
运行前面的代码,您将得到这样的结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\file.py
Hi there!
This is a new file.
We just added text to it!
哇哦!
让我们现在尝试追加。
file = open('newFile.txt','a')
file.write('\nThis is the last line')
file = open('newFile.txt','r')
print(file.read())
运行前面的代码,您将得到这样的结果:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\file.py
Hi there!
This is a new file.
We just added text to it!
This is the last line
这是一个非常强大的功能,可以使编程桌面应用,或任何应用,对你来说非常容易!
迷你项目-用文件介绍
这将是一个非常简单的项目。我们将在您选择的文件夹中创建一个名为 introduction.txt 的文本文件。我们将通过 Python 代码编写对该文件的介绍,最后,我们将在 Shell 中打印该介绍。简单!
我们可以开始了吗?
- 我将在下面的路径中创建我的文件:
G:\\Python\introduction.txt
我也可以用“x ”,但是我用的是“w ”,这样我就不用再以写模式打开文件了。
- 然后,我要写苏珊对它的介绍:
f = open('G:\\Python\introduction.txt','w')
- 现在,让我们把它打印出来。让我们再次打开我们的文件,但这一次是在读模式下,一边读一边打印它的内容,最后关闭它。
f.write('''Hi, I'm Susan.
I'm 9 years old.
My puppy's name is Barky.
He loves me very very much! :)''')
f = open('G:\\Python\introduction.txt','r')
print(f.read())
f.close()
现在,当我们运行程序时,我们会得到这个:
= RESTART: C:\Users\aarthi\AppData\Local\Programs\Python\Python38-32\file.py
Hi, I'm Susan.
I'm 9 years old.
My puppy's name is Barky.
He loves me very very much! :)
完美!
摘要
在这一章中,我们学习了所有关于文件的知识,从你的 Python 代码中创建它们,读取它们,将它们存储在变量中,在你的程序中操作文件,等等。
在下一章,让我们学习一下 Tkinter ,一个让你创建桌面应用的 Python 包。