原文:
inventwithpython.com/invent4thed/chapter0.html译者:飞龙 协议:CC BY-NC-SA 4.0
没有 No Starch Press 团队的出色工作,这本书就不可能问世。感谢我的出版商 Bill Pollock;感谢我的编辑 Laurel Chun、Jan Cash 和 Tyler Ortman,在整个过程中给予我的难以置信的帮助;感谢我的技术编辑 Ari Lacenski 进行了彻底的审查;感谢 Josh Ellingson 再次为我设计了出色的封面。

当我还是个孩子的时候,我第一次玩视频游戏就迷上了。但我不只是想玩视频游戏,我想制作它们。我找到了一本像这样的书,教我如何编写我的第一个程序和游戏。这很有趣,也很容易。我制作的第一个游戏就像这本书中的游戏一样。它们没有我父母为我买的任天堂游戏那么花哨,但它们是我自己制作的游戏。
现在,作为一个成年人,我依然喜欢编程,并且还能从中获得报酬。但即使你不想成为一名计算机程序员,编程也是一项有用且有趣的技能。它训练你的大脑以逻辑思维,制定计划,并在发现代码错误时重新考虑你的想法。
许多面向初学者的编程书籍分为两类。第一类包括那些不是教授编程而是“游戏创作软件”或者简化了太多以至于所教授的不再是编程的语言。另一类包括那些像数学教科书一样教授编程的书籍——所有原则和概念,读者很少能在现实生活中应用。这本书采取了不同的方法,通过制作视频游戏来教你编程。我会直接展示游戏的源代码,并从示例中解释编程原理。这种方法对我学习编程很有帮助。我学习其他人的程序是如何工作的,我就越能为自己的程序想到更多的点子。
你所需要的只是一台计算机,一个名为 Python 解释器的免费软件,以及这本书。一旦你学会了这本书中的游戏,你就能够自己开发游戏了。
计算机是令人难以置信的机器,学习如何编程它们并不像人们想象的那么难。计算机程序是一堆计算机能够理解的指令,就像故事书是读者能够理解的一堆句子一样。要指导计算机,你需要用计算机能够理解的语言编写程序。这本书将教你一种名为 Python 的编程语言。还有许多其他编程语言可以学习,比如 BASIC、Java、JavaScript、PHP 和 C++。
当我还是个孩子的时候,我学习了 BASIC,但像 Python 这样的新编程语言甚至更容易学习。Python 也被专业程序员在工作中和在编程时使用。而且它完全免费安装和使用——你只需要一个互联网连接来下载它。
因为视频游戏无非就是计算机程序,它们也是由指令组成的。从这本书中你将创建的游戏与 Xbox、PlayStation 或任天堂的游戏相比显得简单。这些游戏没有花哨的图形,因为它们的目的是教你编码基础。它们故意简单,这样你就可以专注于学习编程。游戏不一定要复杂才能有趣!
编程并不难,但很难找到教你用编程做有趣事物的材料。其他计算机书籍涵盖了许多新手程序员不需要的主题。这本书将教你如何编写自己的游戏;你将学到一项有用的技能,并有有趣的游戏可以展示!这本书适合:
在本书的大多数章节中,都介绍和解释了一个新的游戏项目。一些章节涵盖了额外的有用主题,比如调试。随着游戏的使用,新的编程概念也得到了解释,并且这些章节应该按顺序阅读。以下是每个章节的简要概述:
pygame模块,并向您展示如何使用它来绘制 2D 图形。
pygame来制作动画图形。
pygame游戏。
本书的大多数章节都将以章节特色程序的示例运行开始。这个示例运行向你展示了当你运行程序时程序是什么样子的。用户输入的部分以粗体显示。
我建议你自己将每个程序的代码输入到 IDLE 的文件编辑器中,而不是下载或复制粘贴。如果你花时间输入代码,你会记得更多。
在输入本书的源代码时,不要在每行开头输入行号。例如,如果你看到以下代码行,你不需要在左边输入9.,或者紧随其后的一个空格:
number = random.randint(1, 20)你只需要输入这个:
number = random.randint(1, 20)这些数字只是为了让本书能够指明程序中的特定行。它们不是实际程序源代码的一部分。
除了行号,按照本书中的代码精确输入。注意到一些代码行是以四个或八个(或更多)空格缩进的。行首的空格会改变 Python 解释指令的方式,所以它们非常重要。
让我们看一个例子。这里缩进的空格用黑色圆圈(•)标记,这样你就可以看到它们。
while guesses < 10:
••••if number == 42:
••••••••print('Hello')第一行没有缩进,第二行缩进了四个空格,第三行缩进了八个空格。尽管本书中的示例没有黑色圆圈来标记空格,但在 IDLE 中每个字符的宽度都是相同的,所以你可以通过上一行或下一行的字符数量来计算空格的数量。
有些代码指令在书中太长,无法放在一行上,会换到下一行。但是这一行在你的电脑屏幕上是可以放下的,所以不要按回车键,全部在一行上输入。你可以通过左边的行号来看一个新指令何时开始。这个例子只有两条指令:
print('This is the first instruction!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxx')
print('This is the second instruction, not the third instruction.')第一条指令在页面上换行到第二行,但第二行没有行号,所以你可以看到它仍然是代码的第一行。
你需要安装一个叫做 Python 解释器的软件。解释器程序能理解你用 Python 写的指令。从现在开始,我会简称 Python 解释器软件为Python。
在这一部分,我将向你展示如何下载和安装 Python 3——具体来说,是 Python 3.4——在 Windows、OS X 或 Ubuntu 上。Python 有比 3.4 更新的版本,但是pygame模块,它在第 17 章到第 21 章中使用,目前只支持到 3.4。
重要的是要知道 Python 2 和 Python 3 之间有一些重大的区别。本书中的程序使用的是 Python 3,如果你尝试用 Python 2 运行它们,你会得到错误。这是如此重要,事实上,我已经添加了一个卡通企鹅来提醒你。

在 Windows 上,从www.python.org/downloads/release/python-344/下载 Windows x86-64 MSI 安装程序,然后双击它。你可能需要输入计算机的管理员密码。按照安装程序在屏幕上显示的指令安装 Python,如下所列:
在 OS X 上,从www.python.org/downloads/release/python-344/下载 Mac OS X 64 位/32 位安装程序,然后双击它。按照安装程序在屏幕上显示的指令安装 Python,如下所列:
如果您正在运行 Ubuntu,您可以按照以下步骤从 Ubuntu 软件中心安装 Python:
Python。
如果上述步骤不起作用,您可以在www.nostarch.com/inventwithpython/找到替代的 Python 3.4 安装说明。
IDLE 代表Interactive DeveLopment Environment。IDLE 就像一个用于编写 Python 程序的文字处理器。在每个操作系统上启动 IDLE 都是不同的:
IDLE,然后选择IDLE(Python GUI)。
idle3。您也可以点击屏幕顶部的应用程序,然后点击编程和IDLE 3。
当您第一次运行 IDLE 时出现的窗口是交互式 shell,如图 1 所示。您可以在>>>提示符下输入 Python 指令,Python 将执行它们。计算机执行指令后,新的>>>提示符将等待您的下一条指令。

图 1:IDLE 程序的交互式 shell
您可以在www.nostarch.com/inventwithpython/找到本书的源代码文件和其他资源。如果您想要询问与本书相关的编程问题,请访问reddit.com/r/inventwithpython/,或者您可以将您的编程问题发送到[email protected]。
在提问之前,请确保执行以下操作:
www.nostarch.com/inventwithpython#diff在线差异工具检查拼写错误。将您的代码复制并粘贴到差异工具中,以查找书中代码和您的代码之间的任何差异。
请记住,您提出编程问题的措辞越好,其他人就越能帮助您。在提出编程问题时,请执行以下操作:
现在您知道如何寻求帮助,您将很快学会编写自己的电脑游戏!
原文:
inventwithpython.com/invent4thed/chapter1.html译者:飞龙 协议:CC BY-NC-SA 4.0
在您可以制作游戏之前,您需要学习一些基本的编程概念。您将从本章开始学习如何使用 Python 的交互式 shell 并执行基本的算术运算。
本章涵盖的主题
按照“启动 IDLE”中的步骤在第 xxvi 页上启动 IDLE。首先,您将使用 Python 解决一些简单的数学问题。交互式 shell 可以像计算器一样工作。在交互式 shell 的>>>提示符处键入2 + 2,然后按 ENTER 键。 (在某些键盘上,此键是 RETURN。)图 1-1 显示了这个数学问题在交互式 shell 中的样子-请注意它响应数字4。

图 1-1: 在交互式 shell 中输入 2 + 2
这个数学问题是一个简单的编程指令。加号(+)告诉计算机将数字2和2相加。计算机执行此操作,并在下一行返回数字4。表 1-1 列出了 Python 中可用的其他数学符号。
表 1-1: 数学运算符
运算符 | 操作 |
|---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
减号(-)减去数字,星号(*)乘以数字,斜杠(/)除以数字。这样使用时,+,-,*和/被称为运算符。运算符告诉 Python 如何处理它们周围的数字。
整数(或简称整数)是诸如4,99和0的整数。浮点数(或简称浮点数)是分数或带有小数点的数字,如3.5,42.1和5.0。在 Python 中,5是一个整数,但5.0是一个浮点数。这些数字被称为值。(稍后我们将学习除了数字之外的其他种类的值。)在您在 shell 中输入的数学问题中,2和2是整数值。
数学问题2 + 2是表达式的一个例子。如图 1-2 所示,表达式由值(数字)和运算符(数学符号)组成,产生代码可以使用的新值。计算机可以在几秒钟内解决数百万个表达式。

图 1-2:表达式由值和运算符组成。
尝试将其中一些表达式输入交互式 shell,每次输入后按 ENTER:
>>> 2+2+2+2+2
10
>>> 8*6
48
>>> 10-5+6
11
>>> 2 + 2
4这些表达式看起来都像普通的数学方程,但请注意2 + 2示例中的所有空格。在 Python 中,您可以在值和运算符之间添加任意数量的空格。但是,当将它们输入交互式 shell 时,您必须始终从行的开头(没有空格)开始指令。
当计算机解决表达式10 + 5并返回值15时,它已经评估了表达式。评估表达式将表达式减少为单个值,就像解决数学问题将问题减少为单个数字:答案。例如,表达式10 + 5和10 + 3 + 2都求值为15。
当 Python 评估表达式时,它遵循与您进行数学运算时一样的操作顺序。只有几条规则:
表达式 1 + 2 * 3 + 4 求值为 11,而不是 13,因为首先评估 2 * 3。如果表达式是 (1 + 2) * (3 + 4),它将求值为 21,因为括号内的 (1 + 2) 和 (3 + 4) 在乘法之前被评估。
表达式可以是任意大小,但它们总是会求值为一个单一的值。即使单个值也是表达式。例如,表达式 15 求值为值 15。表达式 8 * 3 / 2 + 2 + 7 - 9 通过以下步骤求值为值 12.0:

尽管计算机正在执行所有这些步骤,但你在交互式 shell 中看不到它们。交互式 shell 只会显示结果:
>>> 8 * 3 / 2 + 2 + 7 - 9
12.0注意,带有 / 除法运算符的表达式总是求值为浮点数;例如,24 / 2 求值为 12.0。即使有一个浮点数值的数学运算也会求值为浮点数值,所以 12.0 + 2 求值为 14.0。
如果你在交互式 shell 中输入 5 +,你会得到以下错误消息:
>>> 5 +
SyntaxError: invalid syntax这个错误发生是因为 5 + 不是一个表达式。表达式是由运算符连接的值,+ 运算符期望在它之前和之后有一个值。当期望的值缺失时,会出现错误消息。
SyntaxError 意味着 Python 无法理解指令,因为你输入错误了。计算机编程不仅仅是给计算机指令,还要知道如何正确地给它这些指令。
不过不要担心犯错。错误不会损坏你的计算机。只需在下一个 >>> 提示符下正确地重新输入指令到交互式 shell 中。
当一个表达式求值为一个值时,你可以通过将其存储在变量中来稍后使用该值。把变量想象成一个可以容纳值的盒子。
赋值语句会将一个值存储在变量中。输入变量名称,然后是等号(=),这被称为赋值运算符,然后是要存储在变量中的值。例如,输入以下内容到交互式 shell 中:
>>> spam = 15
>>>spam 变量的盒子现在存储值 15,如图 1-3 所示。

图 1-3:变量就像可以容纳值的盒子。
当你按下 ENTER 键时,你不会看到任何响应。在 Python 中,如果没有出现错误消息,你就知道指令是成功的。>>> 提示符会出现,这样你就可以输入下一个指令。
与表达式不同,语句是不会求值为任何值的指令。这就是为什么在 spam = 15 后的交互式 shell 中的下一行没有显示任何值。如果你对哪些指令是表达式,哪些是语句感到困惑,记住表达式会求值为一个单一的值。任何其他类型的指令都是语句。
变量存储值,而不是表达式。例如,考虑语句 spam = 10 + 5 和 spam = 10 + 7 - 2 中的表达式。它们都求值为 15。最终结果是一样的:两个赋值语句都将值 15 存储在变量 spam 中。
一个好的变量名称描述了它包含的数据。想象一下,你搬到了一个新房子,并且给所有的搬运箱贴上了 东西 的标签。你永远找不到任何东西!spam、eggs 和 bacon 这些变量名称是本书中用于变量的示例名称。
第一次在赋值语句中使用变量时,Python 会创建该变量。要检查变量中的值,输入变量名称到交互式 shell 中:
>>> spam = 15
>>> spam
15表达式 spam 的值是变量 spam 中的值:15。
你也可以在表达式中使用变量。尝试在交互式 shell 中输入以下内容:
>>> spam = 15
>>> spam + 5
20你将变量spam的值设置为15,所以输入spam + 5就像输入表达式15 + 5。以下是spam + 5被评估的步骤:

在赋值语句创建变量之前,你不能使用变量。如果你尝试这样做,Python 会给你一个NameError,因为还没有这样的变量。变量名拼写错误也会导致这个错误:
>>> spam = 15
>>> spma
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
spma
NameError: name 'spma' is not defined出现错误是因为有一个spam变量,但没有spma变量。
你可以通过输入另一个赋值语句来更改变量中存储的值。例如,将以下内容输入交互式 shell 中:
>>> spam = 15
>>> spam + 5
20
>>> spam = 3
>>> spam + 5
8当你第一次输入spam + 5时,表达式的值为20,因为你在spam中存储了15。然而,当你输入spam = 3时,变量的盒子中的值15被替换或覆盖为值3,因为变量一次只能保存一个值。因为spam的值现在是3,所以当你输入spam + 5时,表达式的值为8。覆盖就像是从变量的盒子中取出一个值,然后放入一个新值,如图 1-4 所示。

图 1-4:spam中的值15被3*覆盖。
你甚至可以使用spam变量中的值来为spam赋一个新值:
>>> spam = 15
>>> spam = spam + 5
20赋值语句spam = spam + 5表示,“spam变量的新值将是spam的当前值加上五。”要多次增加spam中的值5,请将以下内容输入交互式 shell 中:
>>> spam = 15
>>> spam = spam + 5
>>> spam = spam + 5
>>> spam = spam + 5
>>> spam
30在这个例子中,你在第一条语句中为spam赋了一个值15。在下一条语句中,你将5加到spam的值上,并将spam赋予新值spam + 5,这个值为20。当你这样做三次时,spam的值为30。
到目前为止,我们只看了一个变量,但是你可以在你的程序中创建尽可能多的变量。例如,让我们给两个名为eggs和bacon的变量分配不同的值,如下所示:
>>> bacon = 10
>>> eggs = 15现在bacon变量中有10,eggs变量中有15。每个变量都是它自己的盒子,有自己的值,如图 1-5 所示。

图 1-5:bacon和eggs变量分别存储值。
在交互式 shell 中输入spam = bacon + eggs,然后检查spam的新值:
>>> bacon = 10
>>> eggs = 15
>>> spam = bacon + eggs
>>> spam
25spam中的值现在是25。当你加上bacon和eggs时,你正在加上它们的值,分别为10和15。变量包含值,而不是表达式,所以spam变量被赋予了值25,而不是表达式bacon + eggs。在spam = bacon + eggs语句将值25赋给spam之后,改变bacon或eggs不会影响spam。
在本章中,你学习了编写 Python 指令的基础知识。因为计算机没有常识,只能理解特定的指令,Python 需要你准确告诉它要做什么。
表达式是值(如2或5)与运算符(如+或-)的组合。Python 可以评估表达式,即将表达式简化为单个值。你可以将值存储在变量中,以便你的程序可以记住这些值并在以后使用它们。
Python 中还有其他类型的运算符和值。在下一章中,你将学习一些更基本的概念,并编写你的第一个程序。你将学习如何在表达式中处理文本。Python 不仅仅局限于数字;它不仅仅是一个计算器!
原文:
inventwithpython.com/invent4thed/chapter2.html译者:飞龙 协议:CC BY-NC-SA 4.0
现在让我们看看 Python 可以用文本做什么。几乎所有程序都向用户显示文本,并且用户通过键盘向程序输入文本。在本章中,您将制作您的第一个程序,该程序可以做这两件事。您将学习如何将文本存储在变量中,组合文本,并在屏幕上显示文本。您将创建的程序显示问候语Hello world!并要求用户输入姓名。
本章涵盖的主题
print() 函数
input() 函数
在 Python 中,文本值称为字符串。字符串值可以像整数或浮点值一样使用。您可以将字符串存储在变量中。在代码中,字符串值以单引号'开始和结束。将此代码输入交互式 shell:
>>> spam = 'hello'单引号告诉 Python 字符串从哪里开始和结束。它们不是字符串值文本的一部分。现在,如果您在交互式 shell 中输入spam,您将看到spam变量的内容。请记住,Python 将变量求值为变量内部存储的值。在这种情况下,这是字符串'hello'。
>>> spam = 'hello'
>>> spam
'hello'字符串可以包含任何键盘字符,并且可以任意长。以下都是字符串的示例:
'hello'
'Hi there!'
'KITTENS'
'7 apples, 14 oranges, 3 lemons'
'Anything not pertaining to elephants is irrelephant.'
'A long time ago, in a galaxy far, far away...'
'O*&#wY%*&OCfsdYO*&gfC%YO*&%3yc8r2'您可以使用运算符将字符串值与运算符组合成表达式,就像整数和浮点值一样。当您使用+运算符组合两个字符串时,称为字符串连接。将'Hello' + 'World!'输入交互式 shell:
>>> 'Hello' + 'World!'
'HelloWorld!'该表达式求值为单个字符串值'HelloWorld!'。两个连接的字符串中没有空格,因此单词之间也没有空格,与以下示例不同:
>>> 'Hello ' + 'World!'
'Hello World!'+ 运算符在字符串和整数值上的工作方式不同,因为它们是不同的数据类型。所有值都有一个数据类型。值'Hello'的数据类型是字符串。值5的数据类型是整数。数据类型告诉 Python 在评估表达式时应该做什么。+ 运算符连接字符串值,但是添加整数和浮点数值。
到目前为止,您一直在逐个输入 IDLE 的交互式 shell 中的指令。但是,当您编写程序时,您会输入多个指令并一次性运行它们,这就是您接下来要做的事情。现在是时候编写您的第一个程序了!
除了解释器,IDLE 还有另一个部分称为文件编辑器。要打开它,请单击交互式 shell 顶部的文件菜单。然后选择新建文件。将出现一个空白窗口,供您输入程序代码,如图 2-1 所示。

图 2-1:文件编辑器(左)和交互式 shell(右)
这两个窗口看起来很相似,但请记住:交互式 shell 将显示>>>提示,而文件编辑器不会。
程序员传统上会让他们的第一个程序在屏幕上显示Hello world!。现在您将创建自己的 Hello World 程序。

当输入程序时,请记住不要输入每行代码开头的数字。它们是为了让本书可以按行号引用代码。文件编辑器的右下角将告诉您光标在哪里,这样您就可以检查自己在哪一行代码上。图 2-2 显示光标在第 1 行(在编辑器上下移动)和第 0 列(在左右移动)。

图 2-2:文件编辑器的右下角告诉您光标在哪一行
将以下文本输入到新的文件编辑器窗口中。这是程序的源代码。它包含了 Python 在运行程序时将遵循的指令。
hello.py
# This program says hello and asks for my name.
print('Hello world!')
print('What is your name?')
myName = input()
print('It is good to meet you, ' + myName)IDLE 将使用不同的颜色写入不同类型的指令。在输入代码后,窗口应该看起来像图 2-3。

图 2-3:输入代码后文件编辑器的样子
检查确保您的 IDLE 窗口看起来一样。
输入源代码后,请单击文件 !image](https://gitcode.net/OpenDocCN/flygon-trans-202401/-/raw/master/docs/inv-uron-cmp-gm-py-4e/img/6213f577c15feb006bdab7161d1cfc75.png) 另存为 进行保存。或者按下 CTRL-S 进行快捷键保存。[图 2-4 显示将打开的另存为窗口。在文件名文本字段中输入hello.py,然后单击保存。

图 2-4:保存程序
在编写程序时,应该经常保存程序。这样,如果计算机崩溃或者您意外退出 IDLE,您不会丢失太多工作。
要加载之前保存的程序,请单击文件

打开。在出现的窗口中选择hello.py文件,然后单击打开按钮。您保存的hello.py程序将在文件编辑器中打开。
现在是运行程序的时候了。单击运行

运行模块。或者从文件编辑器中按下 F5(在 OS X 上是 FN-5)。您的程序将在交互式 shell 中运行。
当程序要求输入您的名字时,请输入。这将看起来像图 2-5。

图 2-5:运行 hello.py 后的交互式 shell
当您输入您的名字并按下回车键时,程序将以您的名字向您问候。恭喜!您已经编写了您的第一个程序,现在是一名计算机程序员。再次按 F5 运行程序,然后输入另一个名字。
如果出现错误,请使用在线 diff 工具将您的代码与本书的代码进行比较,网址为https://www.nostarch.com/inventwithpython#diff](https://www.nostarch.com/inventwithpython#diff)。从文件编辑器中复制并粘贴您的代码到网页上,然后单击比较按钮。该工具将突出显示您的代码与本书中代码之间的任何差异,如[图 2-6 所示。
在编码过程中,如果出现以下形式的NameError,这意味着您正在使用 Python 2 而不是 Python 3。
Hello world!
What is your name?
Albert
Traceback (most recent call last):
File "C:/Python26/test1.py", line 4, in <module>
myName = input()
File "<string>", line 1, in <module>
NameError: name 'Albert' is not defined要解决问题,请安装 Python 3.4 并重新运行程序。(参见“下载和安装 Python”第 xxv 页。)

图 2-6:使用 diff 工具 www.nostarch.com/inventwithpython#diff
每行代码都是 Python 解释的一条指令。这些指令组成了程序。计算机程序的指令就像食谱中的步骤一样。Python 按顺序完成程序中的每个指令,从程序的顶部向下移动。
Python 当前在程序中工作的步骤称为执行。程序开始时,执行位于第一条指令处。执行指令后,Python 会向下移动到下一条指令。
让我们看看代码的每一行都在做什么。我们将从第 1 行开始。
Hello World 程序的第一行是注释:
# This program says hello and asks for my name.井号(#)后面的任何文本都是注释。注释是程序员关于代码功能的注释;它们不是为 Python 编写的,而是为你,程序员。Python 在运行程序时会忽略注释。程序员通常在代码顶部放置注释,以便为他们的程序命名。Hello World 程序中的注释告诉你程序会打招呼并询问你的名字。
函数有点像程序中的迷你程序,其中包含 Python 执行的几条指令。函数的好处是你只需要知道它们做什么,而不需要知道它们是如何做的。Python 已经提供了一些内置函数。我们在 Hello World 程序中使用了print()和input()。
函数调用是一条指令,告诉 Python 运行函数内部的代码。例如,你的程序调用print()函数在屏幕上显示一个字符串。print()函数将你在括号中输入的字符串作为输入,并在屏幕上显示该文本。
Hello World 程序的第 2 行和第 3 行是对print()的调用:
print('Hello world!')
print('What is your name?')函数调用括号中的值是参数。第 2 行print()函数调用的参数是'Hello world!',第 3 行print()函数调用的参数是'What is your name?'。这称为传递参数给函数。
第 4 行是一个带有变量myName和函数调用input()的赋值语句:
myName = input()当调用input()时,程序会等待用户输入文本。用户输入的文本字符串将成为函数调用评估的值。函数调用可以在任何可以使用值的表达式中使用。
函数调用评估的值称为返回值。(实际上,“函数调用返回的值”和“函数调用评估的值”意思相同。)在这种情况下,input()函数的返回值是用户输入的字符串:他们的名字。如果用户输入Albert,input()函数调用将求值为字符串'Albert'。评估如下:

这就是字符串值'Albert'存储在myName变量中的方式。
Hello World 程序的最后一行是另一个print()函数调用:
print('It is good to meet you, ' + myName)表达式'It is good to meet you, ' + myName在print()的括号中。因为参数总是单个值,Python 首先评估这个表达式,然后将该值作为参数传递。如果myName中存储的是'Albert',评估如下:

这就是程序通过名字向用户问候的方式。
一旦程序执行最后一行,它就会终止或退出。这意味着程序停止运行。Python 忘记了所有存储在变量中的值,包括存储在myName中的字符串。如果再次运行程序并输入不同的名称,程序将认为那是你的名字。
Hello world!
What is your name?
Carolyn
It is good to meet you, Carolyn记住,计算机会完全按照你编程的指令执行。计算机很笨,只会严格按照你给它的指令执行。计算机不在乎你输入你的名字、别人的名字或者一些愚蠢的东西。输入任何你想输入的东西。计算机会以同样的方式对待它:
Hello world!
What is your name?
poop
It is good to meet you, poop给变量起描述性的名称可以更容易理解程序的功能。您可以将myName变量命名为abrahamLincoln或nAmE,Python 也会运行程序。但这些名称并不能告诉您有关变量可能包含的信息。正如第 1 章所讨论的,如果您搬家并且将每个搬运箱标记为Stuff,那将毫无帮助!本书的交互式 Shell 示例使用变量名spam、eggs和bacon,因为这些示例中的变量名并不重要。然而,本书的程序都使用描述性名称,您的程序也应该如此。
变量名是区分大小写的,这意味着不同大小写的相同变量名被视为不同的变量。因此,在 Python 中,spam、SPAM、Spam和sPAM是四个不同的变量。它们各自包含自己的值。在程序中使用不同大小写的变量是一个不好的主意。而是应该为您的变量使用描述性的名称。
变量名通常是小写的。如果变量名中有多个单词,最好将第一个单词之后的每个单词大写。例如,变量名whatIHadForBreakfastThisMorning比whatihadforbreakfastthismorning更容易阅读。以这种方式大写您的变量称为驼峰命名法(因为它类似于骆驼背上的驼峰),它可以使您的代码更易读。程序员也更喜欢使用更短的变量名来使代码更易于理解:breakfast或foodThisMorning比whatIHadForBreakfastThisMorning更易读。这些是约定——在 Python 编程中做事情的可选但标准方式。
一旦您了解如何使用字符串和函数,您就可以开始制作与用户交互的程序。这很重要,因为文本是用户和计算机之间主要的交流方式。用户通过键盘使用input()函数输入文本,计算机则使用print()函数在屏幕上显示文本。
字符串只是一种新数据类型的值。所有值都有数据类型,值的数据类型会影响+运算符的功能。
函数用于执行程序中的复杂指令。Python 有许多内置函数,您将在本书中学习到。函数调用可以在表达式中的任何值处使用。
您的程序中 Python 当前正在执行的指令或步骤称为执行。在第 3 章中,您将学习如何使执行以除了直接向下执行程序之外的其他方式移动。一旦您学会了这一点,您就可以开始创建游戏了!
原文:
inventwithpython.com/invent4thed/chapter3.html译者:飞龙 协议:CC BY-NC-SA 4.0

在本章中,你将制作一个猜数字游戏。计算机会想一个从 1 到 20 的秘密数字,并要求用户猜测。每次猜测后,计算机会告诉用户数字是太高还是太低。如果用户能在六次内猜中数字,他们就赢了。
这是一个很好的编程游戏,因为它涵盖了短程序中的许多编程概念。你将学习如何将值转换为不同的数据类型,以及何时需要这样做。由于这个程序是一个游戏,从现在开始我们将称用户为玩家。
本章涵盖的主题
import 语句
randint() 函数
for 语句
str()、int() 和 float() 函数
= 和 == 之间的区别
if 语句
break 语句
当运行猜数字程序时,玩家的输入如下所示。玩家的输入以粗体标记。
Hello! What is your name?
Albert
Well, Albert, I am thinking of a number between 1 and 20.
Take a guess.
10
Your guess is too high.
Take a guess.
2
Your guess is too low.
Take a guess.
4
Good job, Albert! You guessed my number in 3 guesses!通过单击文件

新建窗口 打开一个新的文件编辑器窗口。在出现的空白窗口中,输入源代码并将其保存为 guess.py。然后按 F5 运行程序。

当你把这段代码输入到文件编辑器中时,一定要注意行首的空格。有些行需要缩进四个或八个空格。
如果输入此代码后出现错误,请使用在线差异工具将你输入的代码与本书代码进行比较,网址为 www.nostarch.com/inventwithpython#diff。
guess.py
# This is a Guess the Number game.
import random
guessesTaken = 0
print('Hello! What is your name?')
myName = input()
number = random.randint(1, 20)
print('Well, ' + myName + ', I am thinking of a number between 1 and 20.')
for guessesTaken in range(6):
print('Take a guess.') # Four spaces in front of "print"
guess = input()
guess = int(guess)
if guess < number:
print('Your guess is too low.') # Eight spaces in front of "print"
if guess > number:
print('Your guess is too high.')
if guess == number:
break
if guess == number:
guessesTaken = str(guessesTaken + 1)
print('Good job, ' + myName + '! You guessed my number in ' +
guessesTaken + ' guesses!')
if guess != number:
number = str(number)
print('Nope. The number I was thinking of was ' + number + '.')让我们来看看这个程序的前两行:
# This is a Guess the Number game.
import random第一行是一个注释,你在第 2 章中见过。记住 Python 会忽略 # 字符后的所有内容。这里的注释只是提醒我们这个程序的作用是什么。
第二行是一个 import 语句。记住,语句是执行某些操作的指令,但不像表达式那样求值。你已经见过赋值语句,它将一个值存储在一个变量中。
虽然 Python 包含许多内置函数,但有些函数是写在称为模块的单独程序中的。你可以通过使用 import 语句将这些函数的模块导入到你的程序中来使用这些函数。
第 2 行导入了 random 模块,以便程序可以调用 randint() 函数。这个函数将为玩家生成一个随机数来猜测。
现在你已经导入了 random 模块,需要设置一些变量来存储程序稍后将使用的值。
第 4 行创建了一个名为 guessesTaken 的新变量:
guessesTaken = 0你将把玩家猜测的次数存储在这个变量中。由于在程序的这一点上玩家还没有进行任何猜测,所以在这里存储整数 0。
print('Hello! What is your name?')
myName = input()第 6 行和第 7 行与第 2 章中的 Hello World 程序中的行相同。程序员经常重用其他程序中的代码来节省工作量。
第 6 行是对 print() 的函数调用。记住,函数就像你程序中的一个小型程序。当你的程序调用一个函数时,它会运行这个小程序。print() 中的代码会在屏幕上显示你传递给它的字符串参数。
第 7 行让玩家输入他们的名字并将其存储在 myName 变量中。记住,这个字符串可能并不是玩家的真实姓名;它只是玩家输入的任何字符串。计算机是愚蠢的,会按照它们的指令执行,不管怎样。
现在你的其他变量都设置好了,你可以使用random模块的函数来设置计算机的秘密数字:
number = random.randint(1, 20)第 9 行调用了一个名为randint()的新函数,并将返回值存储在number中。记住,函数调用可以是表达式的一部分,因为它们会求值为一个值。
randint()函数由random模块提供,所以你必须使用random.randint()(别忘了句号!)告诉 Python 函数randint()在random模块中。
randint()将返回两个整数参数之间(包括这两个整数)的随机整数。第 9 行在函数名后的括号内传递了用逗号分隔的1和20。randint()返回的随机整数存储在一个名为number的变量中——这就是玩家试图猜测的秘密数字。
只需片刻,回到交互式 shell,输入import random导入random模块。然后输入random.randint(1, 20)看看函数调用的结果。它将返回一个介于1和20之间的整数。再次重复代码,函数调用将返回另一个整数。randint()函数每次返回一个随机整数,就像掷骰子每次都会得到一个随机数一样。例如,输入以下内容到交互式 shell。当你调用randint()函数时得到的结果可能会不同(毕竟是随机的!)。
>>> import random
>>> random.randint(1, 20)
12
>>> random.randint(1, 20)
18
>>> random.randint(1, 20)
3
>>> random.randint(1, 20)
18
>>> random.randint(1, 20)
7你也可以通过改变参数尝试不同范围的数字。例如,输入random.randint(1, 4)来获得介于1和4之间的整数(包括1和4)。或者尝试random.randint(1000, 2000)来获得介于1000和2000之间的整数。
在交互式 shell 中输入此代码,看看你得到了什么数字:
>>> random.randint(1, 4)
3
>>> random.randint(1000, 2000)
1294你可以稍微改变游戏的代码,使游戏的行为有所不同。在我们的原始代码中,我们使用介于1和20之间的整数:
number = random.randint(1, 20)
print('Well, ' + myName + ', I am thinking of a number between 1 and 20.')尝试将整数范围改为(1, 100):
number = random.randint(1, 100)
print('Well, ' + myName + ', I am thinking of a number between 1 and 100.')现在计算机将想一个介于1和100之间的整数,而不是1和20。改变第 9 行将改变随机数的范围,但记得同时改变第 10 行,以便游戏告诉玩家新的范围而不是旧的范围。
你可以在游戏中随时使用randint()函数添加随机性。你会在许多游戏中使用随机性。(想想有多少桌游使用骰子。)
计算机给number分配一个随机整数后,会向玩家打招呼:
print('Well, ' + myName + ', I am thinking of a number between 1 and 20.')在第 10 行,print()欢迎玩家,并告诉他们计算机正在想一个随机数。
乍一看,第 10 行可能看起来有多个字符串参数,但仔细检查一下。三个字符串之间的+运算符将它们连接成一个字符串。而这个字符串是传递给print()的参数。如果你仔细看,你会发现逗号在引号内并且是字符串的一部分。
在之前的章节中,程序执行从程序顶部的指令开始,直接向下移动,按顺序执行每个指令。但是通过for、if、else和break语句,你可以根据条件使执行循环或跳过指令。这些类型的语句是流程控制语句,因为它们改变程序执行的流程,使其在程序中移动时改变。
第 12 行是一个for语句,表示for循环的开始:
for guessesTaken in range(6):循环让你可以一遍又一遍地执行代码。第 12 行将重复其代码六次。for语句以for关键字开始,后面跟着一个新的变量名、in关键字、调用range()函数指定它应该执行的循环次数,以及一个冒号。让我们再讨论一些其他概念,这样你就可以使用循环了。
几行代码可以组合在一起形成一个块。代码块中的每一行都至少以与块中第一行相同数量的空格开头。通过查看行首的空格数量,可以确定块的开始和结束。这就是所谓的缩进。
Python 程序员通常使用四个额外空格来开始一个块。任何后续的行,只要缩进相同,都是块的一部分。当有一行代码的缩进与块开始之前的缩进相同时,块就结束了。也可以在其他块内有块。图 3-1 显示了一个带有轮廓和编号的代码图。

图 3-1:块及其缩进的示例。灰色点代表空格。
在图 3-1 中,第 12 行没有缩进,也不在任何块内。第 13 行缩进了四个空格。由于这一行的缩进比上一行多,一个新的块从这里开始。之后的每一行,只要缩进相同或更多,都被视为块 ➊ 的一部分。如果 Python 遇到另一行的缩进少于块的第一行,那么块已经结束。空行会被忽略。
第 18 行缩进了八个空格,开始了块 ➋。这个块是在块 ➊ 内的。但是下一行,第 20 行,只缩进了四个空格。由于缩进减少,您知道第 18 行的块 ➋ 已经结束了,并且因为第 20 行的缩进与第 13 行相同,所以它在块 ➊ 中。
第 21 行再次增加缩进到八个空格,因此又开始了一个新的块:块 ➌。在第 23 行,我们退出了块 ➌,在第 24 行,我们进入了块 ➍。块 ➊ 和块 ➍ 都在第 24 行结束。
for语句标志着循环的开始。循环重复执行相同的代码。当执行到达for语句时,它进入for语句后面的块。在运行完块中的所有代码后,执行将返回到块的顶部,重新运行所有代码。
在交互式 shell 中输入以下内容:
>>> for i in range(3):
print('Hello! i is set to', i)
Hello! i is set to 0
Hello! i is set to 1
Hello! i is set to 2注意,在输入for i in range(3):并按 ENTER 后,交互式 shell 没有显示另一个>>>提示,因为它期望您输入一块代码。在输入最后一条指令后再次按 ENTER,告诉交互式 shell 您已经输入完代码块了。(这仅适用于在交互式 shell 中工作时。在文件编辑器中编写*.py*文件时,不需要插入空行。)
让我们看一下guess.py第 12 行的for循环:
for guessesTaken in range(6):
print('Take a guess.') # Four spaces in front of "print"
guess = input()
guess = int(guess)
if guess < number:
print('Your guess is too low.') # Eight spaces in front of "print"
if guess > number:
print('Your guess is too high.')
if guess == number:
break
if guess == number:在猜数字游戏中,for块从第 12 行的for语句开始,而for块之后的第一行是第 26 行。
for语句的条件后总是有一个冒号(:)。以冒号结尾的语句期望下一行有一个新的块。这在图 3-2 中有所体现。

图 3-2:循环执行流
图 3-2 显示了执行流程。执行将进入第 13 行的for块并继续向下进行。一旦程序到达for块的末尾,执行不会继续向下执行,而是会循环回到第 13 行for块的开始。这样做了六次,因为for语句中调用了range(6)函数。执行循环的每一次称为迭代。
将for语句视为“执行以下代码块一定次数”。
第 13 行和第 14 行要求玩家猜测秘密数字,并让他们输入他们的猜测:
print('Take a guess.') # Four spaces in front of "print"
guess = input()玩家输入的数字存储在名为guess的变量中。
第 15 行调用了一个名为int()的新函数:
guess = int(guess)int()函数接受一个参数,并将参数的值作为整数返回。
在交互式 shell 中输入以下内容,以查看int()函数的工作原理:
>>> int('42')
42int('42')调用将返回整数值42。
>>> 3 + int('2')
53 + int('2')这一行显示了一个使用int()返回值作为表达式一部分的表达式。它求值为整数值5:

尽管你可以将字符串传递给int(),但你不能传递任意字符串。将'forty-two'传递给int()将导致错误:
>>> int('forty-two')
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
int('forty-two')
ValueError: invalid literal for int() with base 10: 'forty-two'传递给int()的字符串必须由数字组成。
在猜数字游戏中,我们使用input()函数获取玩家的数字。记住,input()函数总是返回玩家输入的文本的字符串。如果玩家输入5,input()函数将返回字符串值'5',而不是整数值5。但是我们稍后需要将玩家的数字与整数进行比较,Python 不能使用<和>比较运算符来比较字符串和整数值:
>>> 4 < '5'
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
4 < '5'
TypeError: unorderable types: int() < str()因此,我们需要将字符串转换为整数:
guess = input()
guess = int(guess)在第 14 行,我们将guess变量赋值为玩家输入的数字的字符串值。第 15 行用int()返回的整数值覆盖了guess中的字符串值。代码int(guess)返回了一个基于提供的字符串的新整数值,guess =将该新值赋给了guess。这样,程序后面的代码可以比较guess是否大于、小于或等于number变量中的秘密数字。
float()和str()函数同样会返回传递给它们的参数的浮点数和字符串版本。在交互式 shell 中输入以下内容:
>>> float('42')
42.0
>>> float(42)
42.0当字符串'42'或整数42传递给float()时,将返回浮点数42.0。
现在尝试使用str()函数:
>>> str(42)
'42'
>>> str(42.0)
'42.0'当整数42传递给str()时,将返回字符串'42'。但是当浮点数42.0传递给str()时,将返回字符串'42.0'。
使用int()、float()和str()函数,你可以将一个数据类型的值转换为另一个数据类型的值。
Python 中的每个值都属于一个数据类型。到目前为止介绍的数据类型有整数、浮点数、字符串,现在还有布尔值。布尔数据类型只有两个值:True或False。布尔值必须用大写的T或F输入,其余值的名称用小写。
布尔值可以像其他数据类型一样存储在变量中:
>>> spam = True
>>> eggs = False在这个例子中,你将spam设置为True,将eggs设置为False。记得将第一个字母大写。
你将使用布尔值(简称bools)与比较运算符一起形成条件。我们将先讨论比较运算符,然后再讨论条件。
比较运算符比较两个值,并求值为True或False布尔值。表 3-1 列出了所有比较运算符。
**表 3-1:**比较运算符
运算符 | 操作 |
|---|---|
< | 小于 |
> | 大于 |
<= | 小于或等于 |
>= | 大于或等于 |
== | 等于 |
!= | 不等于 |
你已经了解了+、-、*和/数学运算符。像任何运算符一样,比较运算符与值结合形成表达式,比如guessesTaken < 6。
猜数字程序的第 17 行使用了小于比较运算符:
if guess < number:我们将很快更详细地讨论if语句;现在,让我们只看一下跟在if关键字后面的表达式(guess < number部分)。这个表达式包含两个值(变量guess和number中的值)由一个运算符(<,或小于号)连接而成。
条件是一个将两个值与比较运算符(如<或>)组合的表达式,并求值为布尔值。条件只是另一个名称,用于求值为True或False的表达式。我们使用条件的一个地方是在if语句中。
例如,第 17 行的条件guess < number询问:“guess中存储的值是否小于number中存储的值?”如果是,则条件求值为True。如果不是,则条件求值为False。
假设guess存储整数10,number存储整数16。因为10小于16,所以这个条件求值为布尔值True。评估如下所示:

在交互式 shell 中输入以下表达式以查看它们的布尔结果:
>>> 0 < 6
True
>>> 6 < 0
False条件0 < 6返回布尔值True,因为数字0小于数字6。但是因为6不小于0,所以条件6 < 0求值为False。
请注意,10 < 10求值为False,因为数字10不小于数字10:
>>> 10 < 10
False这些值是相同的。如果 Alice 和 Bob 的身高相同,你不会说 Alice 比 Bob 高或 Alice 比 Bob 矮。这两个陈述都是错误的。
现在将这些表达式输入到交互式 shell 中:
>>> 10 == 10
True
>>> 10 == 11
False
>>> 11 == 10
False
>>> 10 != 10
False在这个例子中,10等于10,所以10 == 10求值为True。但10不等于11,所以10 == 11是False。即使顺序颠倒,11仍然不等于10,所以11 == 10是False。最后,10等于10,所以10 != 10是False。
您还可以使用比较运算符评估字符串表达式:
>>> 'Hello' == 'Hello'
True
>>> 'Goodbye' != 'Hello'
True
>>> 'Hello' == 'HELLO'
False'Hello'等于'Hello',所以'Hello' == 'Hello'是True。'Goodbye'不等于'Hello',所以'Goodbye' != 'Hello'也是True。
请注意,最后一行求值为False。在 Python 中,大写和小写字母不相同,所以'Hello'不等于'HELLO'。
字符串和整数值永远不会相等。例如,将以下内容输入到交互式 shell 中:
>>> 42 == 'Hello'
False
>>> 42 != '42'
True在第一个例子中,42是一个整数,'Hello'是一个字符串,所以这些值不相等,表达式求值为False。在第二个例子中,字符串'42'仍然不是一个整数,所以表达式“整数42不等于字符串'42'”求值为True。
要小心不要混淆赋值运算符=和等于比较运算符==。等号=用于赋值语句将值存储到变量中,而双等号==用于表达式,以查看两个值是否相等。很容易在本意使用一个时意外使用另一个。
也许有助于记住等于比较运算符==和不等于比较运算符!=都有两个字符。
第 17 行是一个if语句:
if guess < number:
print('Your guess is too low.') # Eight spaces in front of "print"if语句后面的代码块将在if语句的条件求值为True时运行。如果条件为False,则跳过if块中的代码。使用if语句,您可以使程序仅在需要时运行特定代码。
第 17 行检查玩家的猜测是否小于计算机的秘密数字。如果是,则执行移动到第 18 行的if块内,并打印一条消息告诉玩家他们的猜测太低了。
第 20 行检查玩家的猜测是否大于秘密数字:
if guess > number:
print('Your guess is too high.')如果这个条件为True,那么print()函数调用会告诉玩家他们的猜测太高。
第 23 行的if语句检查玩家猜测的数字是否等于秘密数字。如果是,程序会执行第 24 行的break语句:
if guess == number:
breakbreak语句告诉执行立即跳出for块,到达for块结束后的第一行。break语句只在循环内找到,比如在for块中。
for块在没有缩进的下一行代码结束,即第 26 行:
if guess == number:执行离开for块,要么是因为它已经循环了六次(当玩家猜错次数用尽时),要么是因为第 24 行的break语句已经执行(当玩家猜对了数字)。
第 26 行检查玩家是否猜对了。如果是,执行进入第 27 行的if块:
guessesTaken = str(guessesTaken + 1)
print('Good job, ' + myName + '! You guessed my number in ' +
guessesTaken + ' guesses!')第 27 行和第 28 行只有在第 26 行的if语句的条件为True时执行(也就是说,如果玩家正确猜到了计算机的数字)。
第 27 行调用str()函数,它返回guessesTaken + 1的字符串形式(因为range函数从 0 到 5 而不是从 1 到 6)。第 28 行连接字符串,告诉玩家他们赢了多少次猜测。只有字符串值可以连接到其他字符串。这就是为什么第 27 行必须将guessesTaken + 1更改为字符串形式。否则,尝试将字符串与整数连接会导致 Python 显示错误。
如果玩家猜错次数用尽,执行将到达这行代码:
if guess != number:第 30 行使用不等于比较运算符!=来检查玩家的最后一次猜测是否不等于秘密数字。如果这个条件计算为True,执行将进入第 31 行的if块。
第 31 行和第 32 行在if块内,只有在第 30 行的条件为True时执行:
number = str(number)
print('Nope. The number I was thinking of was ' + number + '.')在这个块中,程序告诉玩家秘密数字是多少。这需要连接字符串,但number存储的是一个整数值。第 31 行用一个字符串覆盖number,这样它就可以与第 32 行的'Nope. The number I was thinking of was '和'.'字符串连接起来。
此时,执行已经到达代码的末尾,程序终止。恭喜!你刚刚编写了你的第一个真正的游戏!
你可以通过改变玩家获得的猜测次数来调整游戏的难度。要让玩家只有四次猜测,改变第 12 行的代码:
for guessesTaken in range(4):通过将4传递给range(),你确保循环内的代码只运行四次,而不是六次。这会使游戏变得更加困难。要使游戏变得更容易,传递一个更大的整数给range()函数调用。这将导致循环运行几次更多,并接受更多玩家的猜测。
编程只是为程序编写代码的行为,也就是创建可以由计算机执行的程序。
当你看到有人使用计算机程序(例如,玩你的猜数字游戏),你只会看到一些文本出现在屏幕上。程序根据它的指令和玩家用键盘输入的文本(程序的输入)决定在屏幕上显示什么文本(程序的输出)。程序只是一系列根据用户输入进行操作的指令。
有几种指令:
2 + 2计算为4或'Hello' + ' ' + 'World'计算为'Hello World'。当表达式紧邻if和for关键字时,你也可以称它们为条件。
就是这样 - 就这四样东西。当然,关于这四种类型的指令还有许多细节需要学习。在后面的章节中,你将了解更多的数据类型和运算符,更多的流程控制语句,以及许多其他与 Python 一起使用的函数。除了文本之外,还有不同类型的 I/O,比如鼠标输入和声音和图形输出。
原文:
inventwithpython.com/invent4thed/chapter4.html译者:飞龙 协议:CC BY-NC-SA 4.0
本章的程序向用户讲述了一些笑话,并演示了更高级的使用字符串与print()函数的方法。本书中的大多数游戏都将使用简单的文本进行输入和输出。输入是用户在键盘上输入的文本,输出是显示在屏幕上的文本。
本章涵盖的主题
print()的end关键字参数来跳过换行
你已经学会了如何使用print()函数显示简单的文本输出。现在让我们更深入地了解 Python 中字符串和print()的工作原理。
当用户运行笑话程序时,他们看到的是这样的:
What do you get when you cross a snowman with a vampire?
Frostbite!
What do dentists call an astronaut's cavity?
A black hole!
Knock knock.
Who's there?
Interrupting cow.
Interrupting cow wh-MOO!通过点击文件

新建窗口,打开一个新的文件编辑器窗口。在出现的空白窗口中,输入源代码并将其保存为jokes.py。然后按 F5 运行程序。

如果输入这段代码后出现错误,请使用在线 diff 工具将你输入的代码与书中的代码进行比较,网址为www.nostarch.com/inventwithpython#diff。
jokes.py
print('What do you get when you cross a snowman with a vampire?')
input()
print('Frostbite!')
print()
print('What do dentists call an astronaut\'s cavity?')
input()
print('A black hole!')
print()
print('Knock knock.')
input()
print("Who's there?")
input()
print('Interrupting cow.')
input()
print('Interrupting cow wh', end='')
print('-MOO!')让我们先看一下代码的前四行:
print('What do you get when you cross a snowman with a vampire?')
input()
print('Frostbite!')
print()第 1 行和第 3 行使用print()函数调用来询问并给出第一个笑话的答案。你不希望用户立即看到笑话的结尾,所以在第一个print()后有一个对input()函数的调用。用户会看到笑话,按 ENTER 键,然后看到结尾。
用户仍然可以输入一个字符串并按 ENTER 键,但是这个返回的字符串并没有被存储在任何变量中。程序会忘记它并移到下一行代码。
最后一个print()函数调用没有字符串参数。这告诉程序只打印一个空行。空行有助于保持文本不显得拥挤。
第 5 到 8 行打印了下一个笑话的问题和答案:
print('What do dentists call an astronaut\'s cavity?')
input()
print('A black hole!')
print()在第 5 行,单引号前面有一个反斜杠:\'。(请注意,\是反斜杠,/是正斜杠。)这个反斜杠告诉你它后面的字母是一个转义字符。转义字符允许你打印出在源代码中难以或不可能输入的特殊字符,比如以单引号开头和结尾的字符串值中的单引号。
在这种情况下,如果我们不包括反斜杠,astronaut\'s中的单引号会被解释为字符串的结束。但是这个引号需要作为字符串的一部分。转义的单引号告诉 Python 应该将单引号包含在字符串中。
但是如果你真的想显示一个反斜杠呢?
从你的jokes.py程序切换到交互式 shell,并输入这个print()语句:
>>> print('They flew away in a green\teal helicopter.')
They flew away in a green eal helicopter.这条指令没有打印出反斜杠,因为teal中的t被解释为转义字符,因为它在反斜杠后面。\t模拟了在键盘上按下 TAB 键。
这行代码将给出正确的输出:
>>> print('They flew away in a green\\teal helicopter.')
They flew away in a green\teal helicopter.这样\\就是一个反斜杠字符,而没有\t被解释为 TAB。
表 4-1 是 Python 中一些转义字符的列表,包括\n,这是换行转义字符,你之前用过。
**表 4-1:**转义字符
转义字符 | 实际打印的内容 |
|---|---|
\\ | 反斜杠(\) |
\' | 单引号(') |
\" | 双引号(") |
\n | 换行 |
\t | 制表符 |
Python 中还有一些其他转义字符,但这些字符是你创建游戏时最有可能需要的字符。
当我们还在交互式 shell 中时,让我们更仔细地看一下引号。在 Python 中,字符串并不总是要用单引号括起来的。你也可以用双引号括起来。这两行打印的是相同的内容:
>>> print('Hello world')
Hello world
>>> print("Hello world")
Hello world但你不能混合使用引号。这行会报错,因为它同时使用了两种引号类型:
>>> print('Hello world")
SyntaxError: EOL while scanning single-quoted string我喜欢使用单引号,这样就不必按住 SHIFT 键来输入它们。它们更容易输入,而 Python 也无所谓。
另外,请注意,就像你需要在单引号括起的字符串中使用\'来表示单引号一样,你需要在双引号括起的字符串中使用\"来表示双引号。看这个例子:
>>> print('I asked to borrow Abe\'s car for a week. He said, "Sure."')
I asked to borrow Abe's car for a week. He said, "Sure."你使用单引号来括起字符串,因此你需要在Abe\'s的单引号前添加反斜杠。但"Sure."中的双引号不需要反斜杠。Python 解释器足够聪明,知道如果一个字符串以一种引号开始,另一种引号并不意味着字符串结束。
现在看另一个例子:
>>> print("She said, \"I can't believe you let them borrow your car.\"")
She said, "I can't believe you let them borrow your car."字符串用双引号括起来,因此你需要为字符串中的所有双引号添加反斜杠。在can't中不需要转义单引号。
总之,在单引号字符串中,你不需要转义双引号,但需要转义单引号;在双引号字符串中,你不需要转义单引号,但需要转义双引号。
现在让我们回到jokes.py,看一下第 9 到 16 行:
print('Knock knock.')
input()
print("Who's there?")
input()
print('Interrupting cow.')
input()
print('Interrupting cow wh', end='')
print('-MOO!')你注意到了第 15 行print()函数的第二个参数吗?通常,print()会在打印的字符串末尾添加一个换行符。这就是为什么空的print()函数会打印一个换行符。但print()可以选择性地有第二个参数:end。
记住,参数是函数调用中传递的值。传递给print()的空字符串称为关键字参数。end=''中的end称为关键字参数。要将关键字参数传递给这个关键字参数,你必须在它之前输入end=。
当我们运行这部分代码时,输出是
Knock knock.
Who's there?
Interrupting cow.
Interrupting cow wh-MOO!因为我们将空字符串传递给了end参数,print()函数会添加一个空字符串而不是添加一个换行符。这就是为什么'-MOO!'出现在前一行的旁边,而不是在自己的一行上。在打印'Interrupting cow wh'字符串后没有换行符。
本章探讨了使用print()函数的不同方式。转义字符用于在代码中使用键盘难以输入的字符。如果你想在字符串中使用特殊字符,你必须使用反斜杠转义字符\,后面跟着另一个字母表示特殊字符。例如,\n表示换行。如果你的特殊字符是反斜杠本身,你使用\\。
print()函数会自动在字符串末尾添加一个换行符。大多数情况下,这是一个方便的快捷方式。但有时你不想要换行符。要更改这一点,你可以将空字符串作为print()的end关键字参数的关键字参数传递。例如,要在屏幕上打印spam而不带换行符,你可以调用print('spam', end='')。