输入与输出 — 写出你的第一个程序¶
这一章讲一件事:让程序跟你说话。 你学两个函数——
print()负责「说」,input()负责「听」——再把它们拼成一个能对话的小程序。 顺带你会碰到写代码的头号小妖怪:引号怎么配对。这一章把它彻底解决。
1. 这一章在全书链条里的位置¶
第 01 章解决了「代码写在哪儿」,这一章解决「代码怎么跟世界打交道」。 输入和输出(合称 I/O)是程序的定义性动作:程序就是「读进一些东西, 算一算,吐出一些东西」的循环,这一章先把「读」和「吐」两个口打通, 计算部分从下一章的变量开始。
2. 顶层全景:三个机制,一张图¶
print(值) → 把值显示到屏幕上,值可以是字符串,也可以一次好几个(逗号隔开)
input('提示语') → 屏幕显示提示语,程序停住等你键盘输入,你按回车后它把你的输入当字符串交回来
print(..., input(...)) → 两个函数可以套在一起:input 先执行,把收到的字符串交给外面的 print
图说:两个函数各管一个方向,套起来就是一问答。
3. 核心原理一:print() — 程序的嘴¶
print() 是 Python 的内建函数(built-in function:语言自带、不用自己写
也不装任何东西就能用的函数)。原书给它的定义很短:把一个值输出到屏幕上1。
写法是 print(值),括号里是你想显示的东西2。
你的第一行程序因此长这样:
跑这个格子,屏幕出现 Hello, world!。逐件拆2:
print是函数的名字;圆括号表示「调用它」——让它真的干活,而不是只写下名字。'Hello, world!'是一个字符串(string:一串文字,Python 里用引号包起来的都算)。 更精确地说它是字面量字符串——「字面」的意思是它写死在那儿、不会改变, 程序跑一百次它也是这串字3。# display a message是注释(comment):#右边的一切,解释器直接跳过, 纯粹写给人看的笔记。注释不影响程序行为,但它决定三个月后的你能不能看懂 自己写的代码4。
print() 一次显示多个值¶
在括号里用逗号隔开多个值,print() 会把它们挨着显示,中间自动补一个空格5:
print('Hello,', 'world!') # 输出:Hello, world!
print('What', 'a', 'wonderful', 'world!') # 输出:What a wonderful world!
注意书上特意点破的一个细节:第一个例子里第一个逗号在引号里面,属于字符串本身; 第二个逗号在引号外面,是分隔两个值的记号5。同样一个符号,位置不同身份不同—— 这在编程里是常态,现在先混个脸熟。
4. 核心原理二:引号 — 字符串的头号小妖怪¶
字符串必须用引号包起来。Python 给你三种包法,这一章全部讲透6。
单引号与双引号:任选,但要配对¶
'Hello, world!' 和 "Hello, world!" 完全等价,输出一模一样7。
那为什么要给两种?为了让你能在字符串里再放引号7:
| 你想输出的内容 | 直接写会怎样 | 两种解法 |
|---|---|---|
It's a beautiful day! |
写成 'It's ...' 时,Python 读到第二个 ' 就以为字符串结束了,后面全乱 → 语法错误 |
① 换双引号包外面:"It's a beautiful day!" ② 转义:'It\'s a beautiful day!' |
He said, "Hello, world!" |
写成 "He said "No!"" 时同理,第二个 " 把字符串提前掐断 → 语法错误 |
① 换单引号包外面:'He said "No!"' ② 转义:"He said \"No!\"" |
转义(escaping)是上面表格里反复出现的那个词,值得正式认识:
在字符前面加一个反斜杠 \,就是在告诉 Python「下一个字符按它本来的样子算,
别按它的特殊身份算」——所以 \' 是一个真的单引号字符,而不是「字符串到此结束」的记号8。
书里给的经验法则:平时用单引号包字符串——这是 Python 圈的习惯写法; 只有字符串内容本身含单引号时,才改用双引号或转义9。
三引号:多行字符串与多行注释¶
用 ''' 或 """ 包起来,就是三引号字符串。它有两个独门用途10:
- 装多行文字,而且原样保留换行。
print('''This is a multiline string''')会真的分三行显示。 - 内容里随便套单双引号都不用转义:
'''She said: "We're good!"'''一点不慌。
同一个记号还有第二份兼职:三引号括起来的内容如果不交给任何函数, 它就是一段多行注释——解释器照样跳过,用来写跨好几行的说明文字11。
5. 核心原理三:input() — 程序的耳朵¶
print() 只能自说自话。想让程序听你说,用 input():
它也是内建函数,作用是「读用户输入,把输入作为字符串返回」12。
运行后,屏幕上出现提示语 What is your name?,光标停在那里等;
你键盘敲 Neo 再按回车,这个格子就把 'Neo' 交出来13。
括号里的 'What is your name?' 叫参数(argument):你交给函数用的那个值。
对 input() 来说,这个参数的内容会被显示出来当提示语,告诉你它想让你输入什么14。
一条会咬人的规则:input() 永远返回字符串,哪怕用户敲的是数字。
用户敲 18,交回来的也是 '18' 这串字符,不是数十八。这一条现在听着抽象,
下一章「变量」和第 3 章的数据类型转换会回来收拾它——先记住「敲什么都是字符串」15。
主线例子:一个完整的问候程序¶
把这一章的机制全部串起来,走一遍:
逐帧回放(你敲的回答以 Neo 为例):
第 1 步 程序从外层 print 开始,发现第一个参数还没着落
第 2 步 内层 input('What is your name? ') 先执行 → 屏幕显示:What is your name?
第 3 步 你敲 Neo,按回车 → input 交出字符串 'Neo'
第 4 步 print 收到全部三个参数:'Hello,'、'Neo'、'!'
第 5 步 屏幕输出:Hello, Neo !
图说:函数套函数时,总是最内层先执行——像先系鞋带再出门。
那个输出里 Neo 和 ! 之间多空格,是因为逗号分隔会补空格;原书演示里就是这么显示的[^16]。
(输入 Neo 是演示用例,来自原书练习题的示例。)
再升级一版,问两次:
跑起来是:先问名(答 Thomas),再问姓(答 Anderson),
最后输出 Thomas Anderson is awesome!17——两个 input 按从左到右的顺序
依次执行,每个都把「等用户按回车」这件事做完才轮到下一个。
一个书里没有答案的小问题值得当场说清:如果用户什么都不敲直接按回车,
input() 照样交差——交回来的是空字符串 ''(一对引号中间什么都没有),
程序不会报错也不会停住25。所以「用户可能乱输入」是真实程序必须考虑的事,
这一章先不展开,但要把这个意识种下。
6. 报错是程序在跟你说话¶
这一章第一次正面遇到报错。写 print('I'm fine.') 时,解释器回你一大段:
别怕,拆开读:SyntaxError = 语法错误,「句子结构不合规矩」;
unterminated string literal = 「有一个字符串没有正确的终止」——
就是那个提前出现的 ' 把字符串拦腰掐断了18。
报错不是失败,是解释器在用最笨但最诚实的方式告诉你它把代码读岔在哪儿。 养成习惯:先读最后一行的错误类别,再回头看它指的那一行。 这一章遇到的两种报错都长这样,诱因都是引号没配对19。
7. 书上的练习长什么样:四道题走一遍¶
这一章的练习题都很短,但每道都对应一个具体的小机关。走一遍,等于把前面三节 再考一次自己22:
第 1 题(引号切换): 用双引号打印 Don't worry, be happy!。
机关:内容里有单引号,外面就用双引号包。print("Don't worry, be happy!")22。
第 2 题(转义): 同一句话,改用转义写。
机关:外面换回单引号,里面的 ' 前面加 \。print('Don\'t worry, be happy!')22。
两题输出一模一样——再次印证「单双引号与转义只是包法不同,包进去的内容不变」。
第 3、4 题(反过来): 打印带双引号的 '"Yes! I promise!"',分别用单引号包、
用转义写。机关与上面镜像22。
第 5 题(多行): 用一个 print() 打出四句诗:
机关:三引号。print('''This\nis\na\npoem\n''') 一次装下所有换行23。
这题考的不是新知识点,而是「看到多行需求,脑子里自动弹出三引号」的条件反射——
这个反射值得练到不假思索。
判断(我们的,不是书里的): 这四道题的安排暗藏一个挺好的顺序: 先练「换引号包」,再练「转义」,再练「三引号」——难度其实递减, 但暴露的犯错点各不相同(配对错误、反斜杠位置、换行保留)。 如果你教别人,照这个顺序出题;如果自己练,把每题的两个解法都写一遍, 「同一句话的两种写法」正是引号规则的最小完备集。 如果错,会错在: 转义写法在真实项目里越来越少见(f-string 和格式化 字符串普及之后),练它的主要价值变成了「读懂老代码」,而不是「写新代码」。
8. 常见踩坑速查(这一章的报错全在这了)¶
把全章的坑收进一张表,撞墙时先查它24:
| 你写的 | 你会看到的 | 原因 | 修法 |
|---|---|---|---|
print('I'm fine.') |
SyntaxError: unterminated string literal |
字符串里的 ' 被当成结束引号 |
外面换双引号,或写 \' |
print("He said "No!"") |
SyntaxError: invalid syntax. Perhaps you forgot a comma? |
同上,双引号版 | 外面换单引号,或写 \" |
print('Hello, world!) |
SyntaxError: unterminated string literal(同类) |
少写结尾引号 | 配对检查 |
print('Python' '3.12')(漏逗号) |
输出 Python3.12——不报错,但不是你想要的 |
相邻字符串被 Python 自动拼接 | 两个参数之间加逗号 |
最后一行那个「不报错但结果不对」的坑书上没讲,我们补在这里:它涉及 Python 的一个 默认行为(相邻字符串自动相接),但入门阶段你只需要知道——少了逗号不一定报错, 所以更要盯着输出看。
判断(我们的,不是书里的): 新人对报错的恐惧,一半来自「以为自己搞砸了大问题」。 这一章级别的报错全部可以翻译成一句人话:引号没配成对。 记住这个翻译,报错就从「红色恐怖」降级成「排字检查」。 如果错,会错在: 真实项目里
SyntaxError的原因远不止引号(缩进、括号、 关键字拼错都触发同一类报错)——这一章的翻译只覆盖引号家族,别外推。
9. 作者的判断与证据¶
- 「单引号是 Python 圈的默认写法」——这是风格约定(业界通行的习惯,不是语言强制), 书里明说推荐单引号的理由是常见、好读、遇到双引号内容时不用转义9。
- 练习题的设计哲学写在练习区的开头:先自己死磕再看答案,而且「书上的答案不是唯一 正确答案」20——这是把练习当体检,不是当临摹。
- 每章末尾的「Interact with GenAI」给了一组向 AI 提问的模板(「
print()是干什么的? input 返回什么类型?」)21,这是本书贯穿的特色设施,后面每章我们都会交代它的用途, 但不再复述具体提示词——它们的价值是引导提问,不是答案本身。
10. 边界与局限¶
input()只认字符串。 想拿到数字要做类型转换——第 03 章才讲。 所以如果现在你想写「问年龄再加一」,会撞墙:'18' + 1直接报错。 这堵墙是书故意留的,别怀疑自己。- 打印格式能精细控制吗? 逗号补空格是默认行为;想不补、想换行符、
想控制小数位数,
print()还有别的参数,本书到第 05 章字符串格式化才展开。 - 没有讲文件读写。 「输入」在这里只指键盘;从文件读、往文件写要到很后面的内容才出现, 本书作为入门书干脆没碰——读到这里你要心里有数:真正的程序大多跟文件打交道。
print()和input()只是门面。 它们背后那套「函数怎么定义、参数怎么传、 返回值怎么接」的完整机制,这本书放到第 09 章才拆。现在你可以先用得欢, 但遇到「为什么有的括号里有引号、有的没有」这类问题,答案是「第 09 章会讲」, 而不是「语法规定如此」——每处写法背后都有机制,只是还没轮到它登场。
11. 可带走的¶
print(值)显示值;多个值用逗号隔开,中间自动补空格5。- 字符串用引号包;单双引号等价,推荐单引号;字符串里有引号就换另一种包或加
\转义78。 '''三引号'''装多行文字、装任意引号;单独摆着就是多行注释1011。#右边是注释,解释器跳过,是写给三个月后的自己看的4。input(提示语)显示提示、等你输入、把输入作为字符串交回来1215。- 函数套函数,最内层先执行16。
SyntaxError先读最后一行,再看它指的那一行18。- 书上的练习答案不是唯一解;先死磕再看答案,卡住时可以拿章末的 GenAI 提示当台阶,但别直接要代码2021。
12. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| print() 与第一行程序 | CHAPTER 2: Input and Output | text/11-ch02-chapter-2-input-and-output.txt:13(搜「display a message」) · text/11-ch02-chapter-2-input-and-output.txt:17(搜「outputs text to the screen」) |
| 字符串字面量与注释 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:21(搜「sequence of characters」) · text/11-ch02-chapter-2-input-and-output.txt:28(搜「in-line comment」) |
| 单双引号与转义 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:58(搜「either single quotation mark」) · text/11-ch02-chapter-2-input-and-output.txt:71(搜「Escaping allows you」) |
| 推荐单引号的理由 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:66(搜「generally recommended」) |
| 三引号:多行字符串与多行注释 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:141(搜「multiline strings」) · text/11-ch02-chapter-2-input-and-output.txt:146(搜「multiline comments」) |
| print 打印多值与逗号空格 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:233(搜「separated by a space」) |
| input() 与提示语、参数 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:301(搜「return it as a string」) · text/11-ch02-chapter-2-input-and-output.txt:303(搜「displayed as a prompt」) |
| input 永远返回字符串 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:328(搜「always returns a string」) |
| 函数套函数的演示 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:335(搜「Hello,', input」) · text/11-ch02-chapter-2-input-and-output.txt:345(搜「first name」) |
| 两种语法错误的实例 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:86(搜「unterminated string literal」) · text/11-ch02-chapter-2-input-and-output.txt:104(搜「invalid syntax」) |
| 练习哲学与 GenAI 提示 | 同上 | text/11-ch02-chapter-2-input-and-output.txt:40(搜「not the only correct ones」) · text/11-ch02-chapter-2-input-and-output.txt:276(搜「purpose of the print()」) |
-
出处:「CHAPTER 2: Input and Output」第 17 段(
text/11-ch02-chapter-2-input-and-output.txt:17,搜「outputs text to the screen」)。原文:「The print() function is a built-in Python function that outputs text to the screen.」 ↩ -
出处:「CHAPTER 2: Input and Output」第 13–27 段(
text/11-ch02-chapter-2-input-and-output.txt:13,搜「display a message」;:26,搜「syntax for the print() function」)。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 21–25 段(
text/11-ch02-chapter-2-input-and-output.txt:23,搜「literal string」)。原文:「The string 'Hello, world!' is a literal string, meaning it's a fixed sequence of characters that doesn't change.」 ↩ -
出处:「CHAPTER 2: Input and Output」第 28–34 段(
text/11-ch02-chapter-2-input-and-output.txt:28,搜「to the right of the #」)。注释被解释器忽略、用于增加可读性,原文明写。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 230–241 段(
text/11-ch02-chapter-2-input-and-output.txt:232,搜「separate values with a comma」;:240,搜「the first comma is within」)。「两个逗号身份不同」这个提醒是原书第 240 段的原意。 ↩↩↩ -
出处:「CHAPTER 2: Input and Output」第 58–75 段(单双引号)与第 141–149 段(三引号),各节标题即原书小节名(SINGLE OR DOUBLE / TRIPLE QUOTATIONS)。 ↩
-
出处:「CHAPTER 2: Input and Output」第 58–65 段(
text/11-ch02-chapter-2-input-and-output.txt:58,搜「either single quotation mark」;:62,搜「contain quotations」)。两种引号等价、为方便内含引号而并存,均为原文明写。 ↩↩↩ -
出处:「CHAPTER 2: Input and Output」第 71–73 段(
text/11-ch02-chapter-2-input-and-output.txt:71,搜「include special characters」)。转义的定义逐字依据原文。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 66–70 段(
text/11-ch02-chapter-2-input-and-output.txt:67,搜「use single quotes for defining strings」)。原文给出两个理由:更常见、更好读;以及字符串含双引号时不用转义。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 141–145 段(
text/11-ch02-chapter-2-input-and-output.txt:141,搜「define multiline strings」;:142,搜「span multiple lines」;:145,搜「don't need to escape」)。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 146–149 段(
text/11-ch02-chapter-2-input-and-output.txt:146,搜「define multiline comments」)。「三引号不交给任何函数就是注释」是对原文「To define a multiline comment, you simply enclose your text in triple quotations」的转述。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 300–301 段(
text/11-ch02-chapter-2-input-and-output.txt:301,搜「return it as a string」;:301,搜「return it as a string」)。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 294–298 段(
text/11-ch02-chapter-2-input-and-output.txt:294,搜「What is your name?」)。演示中输入 Neo 后的回显{"type":"string"}是 Jupyter 环境对返回值类型的标注,说明交回来的是字符串。 ↩ -
出处:「CHAPTER 2: Input and Output」第 302–307 段(
text/11-ch02-chapter-2-input-and-output.txt:302,搜「an argument that the input() function takes」;:303,搜「displayed as a prompt」)。「参数」的中文解释是我们补的;原文称 argument。 ↩ -
出处:「CHAPTER 2: Input and Output」第 326–329 段(
text/11-ch02-chapter-2-input-and-output.txt:328,搜「Even if the user enters a number」)。原文:「Even if the user enters a number, it will be returned as a string.」 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 335–338 段(
text/11-ch02-chapter-2-input-and-output.txt:335,搜「Hello,', input('What is your name?」)。原书演示输出为Hello, Neo !,Neo 与 ! 之间确有空格——这是逗号补空格的直接证据。 ↩ -
出处:「CHAPTER 2: Input and Output」第 345–351 段(
text/11-ch02-chapter-2-input-and-output.txt:345,搜「first name」)。Thomas / Anderson 的例子与原书逐字一致。 ↩ -
出处:「CHAPTER 2: Input and Output」第 83–86 段(
text/11-ch02-chapter-2-input-and-output.txt:86,搜「unterminated string literal」)。报错原文是SyntaxError: unterminated string literal (detected at line 2),且错误信息用^指向出错位置(第 85 段)。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 98–104 段(
text/11-ch02-chapter-2-input-and-output.txt:104,搜「Perhaps you forgot a comma」)。第二种报错是SyntaxError: invalid syntax. Perhaps you forgot a comma?,诱因同为引号抢占。 ↩ -
出处:「CHAPTER 2: Input and Output」第 37–41 段(
text/11-ch02-chapter-2-input-and-output.txt:38,搜「Struggling with the tasks」;:40,搜「not the only correct ones」)。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 255–285 段(
text/11-ch02-chapter-2-input-and-output.txt:276,搜「purpose of the print() function」)。练习区与 GenAI 提示的完整清单见原文,此处只摘主题。 ↩↩ -
出处:「CHAPTER 2: Input and Output」第 116–136 段(
text/11-ch02-chapter-2-input-and-output.txt:117,搜「Don't worry, be happy」)。四道引号练习题及其双解法见原文练习区。 ↩↩↩↩ -
出处:「CHAPTER 2: Input and Output」第 178–194 段(
text/11-ch02-chapter-2-input-and-output.txt:185,搜「This」)。诗题及其三引号解法见原文;「用一次 print 打多行」是原题的要求(第 179 段)。 ↩ -
出处:「CHAPTER 2: Input and Output」第 80–114 段(
text/11-ch02-chapter-2-input-and-output.txt:86,搜「unterminated string literal」;:104,搜「Perhaps you forgot a comma」)。表中前三个坑均出自原书演示;「相邻字符串自动拼接」不在原书,标为补充。 ↩ -
补充(不在书里,来自通用知识):
input()在用户直接按回车时返回空字符串,Python 官方文档对input()的描述是「read a line from input」(读取输入中的一行),行可以为空。原书第 387 段(text/11-ch02-chapter-2-input-and-output.txt:387,搜「presses Enter without entering anything」)把这个问题列进了 GenAI 互动提示,但没有给出答案。 ↩