Python 基础篇(三):你的第一个 Python 程序


第三章. 你的第一个 Python 程序

在前两章中,我们完成了开发环境的搭建:Python 解释器已经安装好,PyCharm 也配置完成,虚拟环境的概念也理解了。但到目前为止,我们还没有真正写过一行代码。

从这一章开始,我们将进入真正的编程世界。我们要做的第一件事,就是让计算机对你说一声"你好"。这听起来很简单,但这个过程会让你理解程序是如何运行的,以及当程序出错时该如何应对。


3.1. Hello World:程序员的第一声问候

3.1.1. 为什么所有编程语言都从 Hello World 开始?

如果你翻开任何一本编程教材,第一个示例程序几乎都是"Hello World"。这不是巧合,而是一个延续了近50年的传统。

这个传统的起源

1978年,两位贝尔实验室的工程师出版了一本书《C程序设计语言》。在这本书的第一章,他们用一个简单的程序作为开篇示例:在屏幕上输出"hello, world"。这个程序只有几行代码,但它验证了三件最重要的事情:

  1. 开发环境能用:编译器安装正确,工具链配置无误
  2. 代码能跑:程序可以成功执行,没有报错
  3. 输出能看到:程序的运行结果能够显示出来

从那以后,"Hello World"成为了编程界的一个仪式。无论你学习哪种编程语言,第一个程序都是让计算机向你问好。这个简单的程序,标志着你正式踏入了编程的世界。

为什么不从更复杂的程序开始?

你可能会想:既然要学编程,为什么不直接做一个有用的程序,比如计算器或者小游戏?

原因很简单:在学习跑步之前,你需要先学会站立。Hello World 程序虽然简单,但它让你熟悉了整个开发流程:创建文件、编写代码、运行程序、查看结果。这个流程会在你未来的每一次编程中重复无数次,我们再上一章已经完成了最简单的 hello world,现在我们再对他进行分析


3.1.2. 程序执行的本质:从文本到指令

你可能会好奇:我们只是在文件里写了一行文字,为什么按下运行按钮后,屏幕上就出现了输出?这个过程中到底发生了什么?

Python 解释器的工作流程

当你点击运行按钮时,PyCharm 会调用 Python 解释器,并把你的代码文件传递给它。解释器会执行以下步骤:

  1. 读取文件:解释器打开 hello.py 文件,读取里面的内容
  2. 解析代码:解释器逐行分析代码,检查语法是否正确
  3. 翻译成指令:解释器把 Python 代码翻译成计算机能理解的机器指令
  4. 执行指令:计算机执行这些指令,产生输出

在我们的例子中,print("Hello, World!") 这行代码被翻译成了一系列指令,这些指令告诉计算机:“在控制台窗口中显示文本 Hello, World!”。

为什么必须先保存文件?

你可能注意到了,我们在运行程序之前,先按了 Ctrl + S 保存文件。这是因为 Python 解释器只能读取磁盘上的文件,而不能读取你在编辑器中输入但还没保存的内容。

如果你修改了代码但没有保存,运行的仍然是上一次保存的版本。这是新手最容易犯的错误之一:明明改了代码,但运行结果没有变化,原因就是忘记保存了。

"运行成功"的标志

当你看到 Process finished with exit code 0 这行提示时,说明程序正常运行结束了。这里的 exit code(退出码)是程序返回给操作系统的一个数字:

  • 0 表示程序正常结束,没有错误
  • 0 的数字(如 12)表示程序遇到了错误

在后面的章节中,当我们的程序出错时,你会看到非 0 的退出码。


3.2. print 函数:程序与你对话的窗口

在上一节中,我们用 print("Hello, World!") 让程序输出了一行文字。现在,我们要深入理解 print 这个函数,因为它是你在学习 Python 过程中使用最频繁的工具之一。

3.2.1. print 的本质:输出到控制台

什么是控制台?

当你运行 Python 程序时,PyCharm 底部弹出的那个黑色(或白色)窗口,就是控制台(Console)。控制台是程序与你交流的地方:程序可以在这里显示信息,你也可以在这里输入信息(我们会在后续章节讲解输入)。

在专业术语中,控制台也被称为"标准输出"(stdout)。当你调用 print() 函数时,Python 会把内容发送到标准输出,然后显示在控制台窗口中。

print 的作用

print 函数的作用很简单:把你想要展示的内容显示出来。这听起来平淡无奇,但它是调试程序最基本的工具。

想象一下,如果没有 print,你的程序就像一个哑巴:它在内部做了很多计算,但你完全看不到过程,也不知道结果对不对。有了 print,你可以随时让程序告诉你:“我现在算到这一步了,结果是这样的。”

一个对比实验

让我们做一个实验。创建一个新文件 silent.py,输入以下代码:

1
result = 10 + 20

运行这个程序,你会发现控制台只显示:

1
Process finished with exit code 0

程序运行了,但你看不到任何输出。这是因为我们只是让 Python 计算了 10 + 20,并把结果存储在变量 result 中,但没有告诉 Python 把结果显示出来。

现在,修改代码,加上 print

1
2
result = 10 + 20
print(result)

再次运行,控制台会显示:

1
2
30
Process finished with exit code 0

这就是 print 的作用:让程序的内部状态变得可见。


3.2.2. 输出多个内容:用逗号分隔

在实际编程中,我们经常需要输出多个信息。比如,你想让程序输出:我的名字是张三,今年25岁

方法 1:拼接成一个字符串

你可能会想到这样写:

1
print("我的名字是张三,今年25岁")

这样确实可以,但如果名字和年龄是变量呢?比如:

1
2
3
name = "张三"
age = 25
print("我的名字是" + name + ",今年" + age + "岁")

运行这段代码,你会发现程序报错了:

1
TypeError: can only concatenate str (not "int") to str

这个错误的意思是:你不能直接把字符串和数字拼接在一起。age 是一个数字(整数),而 "我的名字是" 是一个字符串,Python 不知道该怎么把它们合并。

你可以把 age 转换成字符串:

1
print("我的名字是" + name + ",今年" + str(age) + "岁")

这样可以运行,但代码看起来很乱,到处都是加号和引号。

方法 2:用逗号分隔多个参数

print 函数有一个很方便的特性:它可以接受多个参数,用逗号分隔。Python 会自动把这些参数转换成字符串,然后用空格连接起来。

1
2
3
name = "张三"
age = 25
print("我的名字是", name, ",今年", age, "岁")

运行结果:

1
我的名字是 张三 ,今年 25 岁

注意观察输出:张三 前后、25 前后都自动加上了空格。这是因为 print 默认会在每个参数之间插入一个空格。

这种写法比字符串拼接简洁得多,而且不需要手动转换类型。这是我们推荐的方式。


3.2.3. 控制输出格式:sep 和 end 参数

在上一节的例子中,你可能注意到了一个问题:print 自动在参数之间加了空格,导致输出变成了 我的名字是 张三 ,今年 25 岁,逗号前面多了一个空格,看起来不太自然。

如何去掉这些多余的空格呢?这就需要用到 print 的两个特殊参数:sepend

问题 1:如何去掉自动添加的空格?

sep 参数(separator 的缩写,意为"分隔符")控制多个参数之间用什么字符连接。它的默认值是一个空格 " "

如果我们把 sep 设置为空字符串 "",就可以去掉空格:

1
2
3
name = "张三"
age = 25
print("我的名字是", name, ",今年", age, "岁", sep="")

运行结果:

1
我的名字是张三,今年25岁

完美!现在输出看起来自然多了。

你也可以用其他字符作为分隔符。比如,用短横线连接:

1
print("Python", "很", "简单", sep="-")

输出:

1
Python-很-简单

问题 2:如何让多个 print 输出在同一行?

默认情况下,每次调用 print 都会在输出的末尾加上一个换行符,所以多个 print 会分别占一行:

1
2
3
print("第一行")
print("第二行")
print("第三行")

输出:

1
2
3
第一行
第二行
第三行

但有时候,我们希望多个 print 的输出连在一起。比如,制作一个简单的加载动画:

1
2
3
print("加载中")
print("...")
print("完成!")

默认输出:

1
2
3
加载中
...
完成!

这不是我们想要的效果。我们希望输出是:加载中...完成!

这时候就需要用到 end 参数。end 控制 print 在输出结束后添加什么字符,默认值是换行符 "\n"

如果我们把 end 设置为空字符串 "",就可以让多个 print 输出在同一行:

1
2
3
print("加载中", end="")
print("...", end="")
print("完成!")

输出:

1
加载中...完成!

原理解释

让我们用一个表格来总结 sepend 的作用:

参数作用默认值示例
sep控制多个参数之间的分隔符" "(空格)print("A", "B", sep="-")A-B
end控制输出结束后添加的字符"\n"(换行符)print("A", end="") → 输出后不换行

这两个参数让 print 变得非常灵活。在后续的学习中,你会经常用到它们。


3.2.4. 输出中的特殊字符:换行与制表符

在前面的例子中,我们提到了 "\n" 这个神秘的符号。它是什么意思?为什么要用反斜杠加字母来表示?

场景:如何输出多行文本?

假设你想让程序输出一首诗,每句占一行:

1
2
3
4
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。

你可能会想到这样写:

1
2
3
4
print("床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。")

但这样写会报错:

1
SyntaxError: unterminated string literal (detected at line 1)

错误的原因是:Python 的字符串不能直接跨行。当 Python 看到第一行末尾的引号后面没有配对的引号时,它会认为字符串没有结束,然后在下一行找不到合法的语法,就报错了。

解决方案:使用换行符 \n

\n 是一个特殊字符,叫做"换行符"(newline)。当 Python 遇到 \n 时,会在输出中插入一个换行。

1
print("床前明月光,\n疑是地上霜。\n举头望明月,\n低头思故乡。")

运行结果:

1
2
3
4
床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。

完美!现在每句诗都占一行了。

为什么不能直接按回车键?

你可能会想:为什么不能在代码里直接按回车键,而要用 \n 这种奇怪的写法?

原因是:代码中的换行和输出中的换行是两回事。代码中的换行是为了让代码更易读,而输出中的换行是程序运行时产生的效果。Python 需要一种方式来区分这两者,所以引入了 \n 这个特殊符号。

场景:如何对齐输出?

再看一个场景。假设你想输出一个简单的表格:

1
2
3
姓名    年龄    城市
张三 25 北京
李四 30 上海

如果你用空格来对齐,会发现很难控制:

1
2
3
print("姓名  年龄  城市")
print("张三 25 北京")
print("李四 30 上海")

输出:

1
2
3
姓名  年龄  城市
张三 25 北京
李四 30 上海

看起来还行,但如果名字长度不同,就很难对齐了。

解决方案:使用制表符 \t

\t 是另一个特殊字符,叫做"制表符"(tab)。它的作用是插入一个固定宽度的空白,通常相当于 4 个或 8 个空格。

1
2
3
print("姓名\t年龄\t城市")
print("张三\t25\t北京")
print("李四\t30\t上海")

输出:

1
2
3
姓名    年龄    城市
张三 25 北京
李四 30 上海

现在列对齐了!\t 会自动调整空白的宽度,让内容对齐到下一个制表位。

两个必须掌握的特殊字符

在实际开发中,你会经常用到这两个特殊字符:

特殊字符名称作用示例
\n换行符在输出中插入换行print("第一行\n第二行")
\t制表符在输出中插入固定宽度的空白print("列1\t列2\t列3")

这两个字符是"转义字符"(Escape Character)的一部分。所谓"转义",就是用反斜杠 \ 加上一个字母,来表示一些无法直接输入的特殊字符。


3.3. 当程序出错时:读懂报错信息

在前面的学习中,我们的程序都运行得很顺利。但在实际编程中,出错是家常便饭。即使是经验丰富的程序员,也会经常遇到报错。

关键不在于避免所有错误,而在于学会快速定位和解决错误。而这一切的前提是:读懂 Python 的报错信息。

3.3.1. 制造你的第一个错误

让我们故意写一个错误的程序,来看看 Python 会如何提示我们。

创建一个新文件 error_demo.py,输入以下代码:

1
print("Hello World)

仔细观察这行代码,你会发现一个问题:字符串的开头是双引号 ",但结尾却没有配对的双引号。

保存文件,然后运行。PyCharm 的控制台会显示一大段红色的错误信息:

1
2
3
4
  File "D:/code/error_demo.py", line 1
print("Hello World)
^
SyntaxError: unterminated string literal (detected at line 1)

第一次看到这样的错误信息,你可能会感到困惑:这些英文是什么意思?我该怎么办?

别担心,Python 的报错信息虽然看起来吓人,但它其实是在帮助你。让我们逐层解读这段信息。


3.3.2. 报错信息的三层解码

Python 的报错信息遵循一个固定的格式,包含三个关键部分。理解了这个格式,你就能快速定位问题。

第一层:文件位置

1
File "D:/code/error_demo.py", line 1

这一行告诉你:错误发生在哪个文件的第几行。

  • File "D:/code/error_demo.py":错误在 error_demo.py 这个文件中
  • line 1:错误在第 1 行

这是最重要的信息。当你的项目有很多文件时,这一行会告诉你该去哪个文件找问题。

第二层:错误代码

1
2
print("Hello World)
^

这两行显示了出错的那行代码,并用 ^ 符号标记了 Python 认为错误发生的位置。

在我们的例子中,^ 指向了字符串的末尾,这是 Python 发现问题的地方:它期待看到一个闭合的引号,但没有找到。

第三层:错误类型和描述

1
SyntaxError: unterminated string literal (detected at line 1)

这一行包含两个关键信息:

  1. 错误类型SyntaxError(语法错误)
  2. 错误描述unterminated string literal(未终止的字符串字面量)

让我们把这个错误描述翻译成人话:

  • unterminated:未终止的、没有结束的
  • string literal:字符串字面量(就是指你写的那个字符串)
  • 合起来的意思:你的字符串没有正确结束(缺少闭合引号)

完整的解读流程

当你遇到报错时,按照这个顺序阅读:

  1. 看第一层:确定错误在哪个文件的哪一行
  2. 看第二层:找到出错的代码,观察 ^ 指向的位置
  3. 看第三层:理解错误类型和描述,判断问题的原因

在我们的例子中:

  • 错误在 error_demo.py 的第 1 行
  • 问题出在字符串的末尾
  • 原因是字符串没有闭合引号

解决方案很明显:在字符串末尾加上 "

1
print("Hello World")

再次运行,程序正常输出了:

1
Hello World

3.3.3. 三个最常见的新手错误

在学习 Python 的初期,有三种错误会反复出现。让我们提前认识它们,这样你遇到时就不会慌张。

错误 1:拼写错误

1
pirnt("Hello")

运行后,你会看到:

1
NameError: name 'pirnt' is not defined

错误解读:

  • NameError:名称错误(Python 不认识这个名字)
  • name 'pirnt' is not defined:名字 pirnt 没有定义

人话翻译: Python 不知道 pirnt 是什么。你可能是想写 print,但拼错了。

如何避免: 仔细检查拼写,利用 PyCharm 的自动补全功能。当你输入 pri 时,PyCharm 会自动提示 print,按 Tab 键就能补全。


错误 2:缩进错误

1
2
print("第一行")
print("第二行")

注意第二行前面多了两个空格。运行后,你会看到:

1
IndentationError: unexpected indent

错误解读:

  • IndentationError:缩进错误
  • unexpected indent:意外的缩进

人话翻译: Python 发现你的代码缩进了,但这里不应该缩进。

Python 的缩进规则: Python 用缩进来表示代码的层级关系(我们会在后续章节详细讲解)。在目前的学习阶段,所有代码都应该顶格写,不要随意缩进。

如何避免: 确保代码都从行首开始,不要在前面加空格或 Tab。


错误 3:中文符号

1
print"Hello"

仔细观察,这里的括号不是英文的 (),而是中文的 ()。运行后,你会看到:

1
SyntaxError: invalid character '(' (U+FF08)

错误解读:

  • SyntaxError:语法错误
  • invalid character '(':无效的字符

人话翻译: Python 不认识中文符号

如何避免:

  1. 在写代码时,确保输入法切换到英文模式
  2. 如果你用的是中文输入法,在 PyCharm 中输入代码时会自动切换到英文符号
  3. 养成习惯:代码区域全部用英文,只有字符串内容(如 print("你好") 中的"你好")才用中文

避坑指南总结

错误类型典型报错原因解决方案
拼写错误NameError函数名、变量名拼错仔细检查拼写,使用自动补全
缩进错误IndentationError代码前面多了空格确保代码顶格写
中文符号SyntaxError: invalid character用了中文标点符号切换到英文输入法

记住这三种错误,你就能避开新手阶段 80% 的坑。


3.4. 调试工具:让程序"慢动作回放"

在前面的学习中,我们用 print 来查看程序的输出。但当程序变得复杂时,到处加 print 会让代码变得很乱。更重要的是,有时候你需要看到程序运行的每一步,而不仅仅是最终结果。

这时候,我们需要一个更强大的工具:调试器(Debugger)。

3.4.1. 为什么需要调试?

场景:一个简单的计算程序

假设你写了一个计算打折价格的程序:

1
2
3
4
price = 100
discount = 0.8
final_price = price * discount
print("最终价格:", final_price)

运行后,输出:

1
最终价格: 80.0

看起来没问题。但如果你想验证计算过程,确认每一步都是对的,该怎么办?

传统方法:到处加 print

你可能会这样做:

1
2
3
4
5
6
7
price = 100
print("原价:", price) # 调试用
discount = 0.8
print("折扣:", discount) # 调试用
final_price = price * discount
print("计算结果:", final_price) # 调试用
print("最终价格:", final_price)

运行后:

1
2
3
4
原价: 100
折扣: 0.8
计算结果: 80.0
最终价格: 80.0

这样确实能看到每一步的值,但有两个问题:

  1. 代码变乱了:到处都是调试用的 print,真正的业务逻辑被淹没了
  2. 调试完要删除:验证完成后,你需要把这些 print 一个个删掉,很麻烦

更好的方法:使用调试工具

PyCharm 内置了强大的调试器,它可以让程序"暂停"在任意一行,让你查看当前所有变量的值,然后一行一行地执行代码。这就像给程序按下了"慢动作"按钮。


3.4.2. 设置断点:让程序暂停

什么是断点?

断点(Breakpoint)就是你在代码中设置的一个"暂停标记"。当程序运行到这一行时,会自动暂停,等待你的指令。

如何设置断点?

在 PyCharm 中设置断点非常简单:

步骤 1: 打开 discount.py 文件

步骤 2: 在代码编辑区域的左侧,找到行号。在第 1 行(price = 100)的行号位置点击一下。

你会看到出现了一个红色的圆点,这就是断点。

image-20260207231530989

步骤 3: 点击右上角的"虫子"图标(Debug 按钮),或者按快捷键 Shift + F9(Windows)/ Control + D(macOS)。

这次我们不是用"运行"(Run),而是用"调试"(Debug)模式启动程序。

观察界面变化

程序启动后,会立即暂停在第 1 行。此时,PyCharm 的界面会发生变化:

  1. 代码区域:第 1 行被蓝色高亮,表示程序当前停在这里
  2. 底部窗口:出现了"Debugger"标签页,显示了很多信息
  3. 变量区:在 Debugger 窗口中,有一个"Variables"区域,但现在是空的(因为还没有执行任何代码)

程序暂停的含义

当程序暂停在第 1 行时,这意味着:

  • 第 1 行的代码还没有执行
  • 程序正在等待你的指令:是继续执行,还是单步执行,还是停止

3.4.3. 单步执行:一行一行看代码运行

现在,程序暂停在第 1 行。我们要让它一行一行地执行,观察每一步的变化。

三个关键按钮

在 Debugger 窗口的顶部,有一排按钮。我们需要认识其中三个:

名称快捷键作用
Step OverF8执行当前行,跳到下一行
Step IntoF7进入函数内部(暂时用不到)
ResumeF9继续运行到下一个断点

现在,我们只需要用 Step Over(F8)

image-20260207231656900

实战演示:逐步执行代码

第 1 步: 按下 F8 键(或点击 Step Over 按钮)

程序执行了第 1 行代码 price = 100,然后跳到了第 2 行。

观察变量区,你会看到出现了一个新变量:

1
price = 100

这说明第 1 行代码已经执行完成,变量 price 被创建了,值是 100

第 2 步: 再按一次 F8

程序执行了第 2 行代码 discount = 0.8,跳到了第 3 行。

变量区现在显示:

1
2
price = 100
discount = 0.8

第 3 步: 再按一次 F8

程序执行了第 3 行代码 final_price = price * discount,跳到了第 4 行。

变量区现在显示:

1
2
3
price = 100
discount = 0.8
final_price = 80.0

你可以清楚地看到,final_price 的值是 80.0,这是 100 * 0.8 的结果。

第 4 步: 再按一次 F8

程序执行了第 4 行代码 print("最终价格:", final_price),控制台输出了:

1
最终价格: 80.0

此时,程序已经执行完所有代码,调试结束。


3.4.4. 查看变量值:程序在想什么

在刚才的演示中,我们看到了变量区实时显示了所有变量的值。这是调试器最强大的功能之一。

变量区的作用

变量区(Variables)会显示当前作用域内的所有变量,包括:

  • 变量名:如 pricediscount
  • 变量值:如 1000.8
  • 变量类型:如 int(整数)、float(浮点数)

当你单步执行代码时,变量区会实时更新。如果某个变量的值发生了变化,它会用不同的颜色高亮显示,提醒你注意。

对比:print vs 调试器

让我们对比一下两种方法:

方法优点缺点适用场景
到处加 print简单直接,不需要学习工具代码变乱,调试完要删除快速验证某个值
使用调试器代码干净,可以看到所有变量,可控制执行流程需要学习操作复杂逻辑,需要逐步验证

建议:

  • 如果只是想快速看一个变量的值,用 print 就够了
  • 如果程序逻辑复杂,或者不确定哪里出错了,用调试器

调试器的其他功能(预告)

调试器还有很多高级功能,比如:

  • 条件断点:只有满足某个条件时才暂停
  • 监视表达式:实时计算某个表达式的值
  • 调用栈:查看函数的调用关系

这些功能我们会在后续章节逐步介绍。现在,你只需要掌握"设置断点 + 单步执行"这两个基本操作就够了。


3.5. 本章小结

核心要点

要点何时使用关键动作
print 基础输出信息到控制台print("内容")
print 多参数输出多个内容print("A", "B", "C")
sep 和 end控制输出格式print(..., sep="", end="")
换行符 \n在输出中换行print("第一行\n第二行")
制表符 \t对齐输出print("列1\t列2")
读懂报错程序出错时看文件位置、错误类型、描述
断点调试验证程序逻辑设断点 → Debug运行 → F8单步

本章回顾

本章完成了从"环境搭建"到"真正编程"的跨越。我们学会了:

  1. 编写并运行第一个程序:理解了 Hello World 的意义,掌握了在 PyCharm 中创建文件、编写代码、运行程序的完整流程
  2. 使用 print 函数:学会了输出单个内容、多个内容,以及使用 sepend 参数控制输出格式
  3. 处理特殊字符:掌握了 \n(换行)和 \t(制表符)的用法,能够输出多行文本和对齐的表格
  4. 读懂报错信息:学会了解读 Python 报错的三层结构,认识了三种最常见的新手错误
  5. 使用调试工具:掌握了设置断点、单步执行、查看变量值的基本调试技能

这些技能是后续所有学习的基础。从下一章开始,我们将学习变量、数据类型等核心概念。但无论学到哪里,print 和调试器都会是你最常用的工具。