1. Python 初步
欢迎开启你的 Python 编程之旅!本章将引导你完成关键的第一步:理解什么是 Python、如何在电脑上安装它,以及如何运行你的第一段 Python 代码。读完本章后,你将能够比较熟练地使用 Python 的交互式命令行,创建并运行脚本文件,并理解 Python 给出的基础错误信息。
1.1)什么是程序,Python 在其中做什么?
在具体进入 Python 之前,先来理解什么是程序,以及 Python 在创建程序中扮演的角色。
1.1.1)理解程序
程序(program)是一组告诉计算机“该做什么”的指令。就像菜谱一步步教你如何烤蛋糕一样,程序也一步步告诉计算机如何完成一项任务。这些任务可以从简单的计算到复杂的操作,比如显示网页、处理图像或控制机器人。
计算机不会直接理解英语或西班牙语等人类语言。它们只理解机器码(machine code)——由二进制数字(0 和 1)组成的序列,用来表示非常基础的操作。对人类来说,直接用机器码写程序会极其困难且容易出错。
这就是编程语言(programming languages)存在的原因。编程语言是一种人类可读的方式,用来编写能够被翻译成机器码的指令。Python 就是其中一种编程语言,它被设计得特别便于人类阅读和编写。
1.1.2)Python 的特别之处
Python 是一种高级编程语言(high-level programming language),这意味着它屏蔽了很多在低级语言中你需要自己处理的复杂细节。下面是 Python 之所以对初学者和专业人士都很有吸引力的原因:
可读性强的语法:Python 代码读起来几乎像英语。例如,要在 Python 中打印 “Hello, World!” 时,你可以写:
# hello_simple.py
print("Hello, World!")输出:
Hello, World!和 C 或 Java 等语言相比,完成同样的任务,它们需要更多样板代码。
解释型语言:Python 是一种解释型语言(interpreted language)。这意味着你不需要在运行前把代码编译成机器码。相反,一个叫做Python 解释器(Python interpreter)的程序会逐行读取并执行你的代码。这样会让开发更快,因为你可以立即看到代码修改的结果。
用途广泛且功能强大:尽管对初学者很友好,Python 仍广泛用于专业场景,包括:
- Web 开发(网站和 Web 应用)
- 数据分析与可视化
- 机器学习和人工智能
- 科学计算
- 自动化和脚本编写
- 游戏开发
- 以及更多
庞大的社区与库生态:Python 拥有庞大的用户社区,以及成千上万扩展其功能的预写代码库。这意味着很多常见问题的解决方案往往只需导入一个库即可获得。
1.1.3)Python 如何执行你的代码
当你编写并运行 Python 代码时,幕后大致会发生以下过程:
-
你编写代码:你创建一个包含 Python 指令的文件,或者直接在 Python 交互式命令行中输入代码。
-
解释器读取你的代码:Python 解释器会检查代码是否有语法错误(也就是你写代码的方式是否有问题)。
-
翻译为字节码:如果没有语法错误,Python 会将代码翻译为一种叫作字节码(bytecode)的中间形式。字节码是你代码的中间表示——是一种介于 Python 和机器码之间的语言。对计算机来说,它比 Python 更容易执行,但又比纯机器码更抽象。
-
执行:Python 虚拟机(Python Virtual Machine,PVM)执行这些字节码,完成你指定的操作。
-
输出:你会看到程序的结果——可能是屏幕上的文本、被创建的文件,或任何其他动作。
这一过程的妙处在于,你通常不需要操心大部分步骤。你只需写代码、运行,并查看结果,剩下的由解释器来处理。
1.2)安装 Python 并运行解释器
要开始用 Python 编程,首先需要在电脑上安装 Python。本节将引导你完成安装过程,并验证一切工作正常。
1.2.1)检查是否已安装 Python
有些操作系统预装了 Python。在下载任何东西之前,先检查一下系统中是否已经有 Python。
在 Windows 上:
-
打开命令提示符(Command Prompt):
- 按
Windows + R打开“运行”对话框 - 输入
cmd并回车
- 按
-
输入下面的命令并回车:
python --version如果已安装 Python,你会看到类似这样的输出:
Python 3.11.5如果你看到类似 'python' is not recognized as an internal or external command 的错误信息,说明没有安装 Python,或者没有在系统 PATH 中。
在 macOS 上:
-
打开 Terminal(终端)应用:
- 按
Command + Space打开 Spotlight - 输入
Terminal并回车
- 按
-
输入下面的命令并回车:
python3 --version注意:在 macOS 上通常使用 python3 而不是 python,因为 python 可能指向已经过时的 Python 2。
如果安装了 Python 3,你会看到类似输出:
Python 3.11.5在 Linux 上:
-
打开终端应用(不同发行版有所不同)
-
输入下面的命令并回车:
python3 --version大多数现代 Linux 发行版都预装了 Python 3。
1.2.2)下载并安装 Python
如果没有安装 Python,或者版本较旧,请按以下步骤安装最新版本。
Windows 安装:
-
访问 Python 官方网站:https://www.python.org/downloads/
-
点击 “Download Python” 按钮(其上会显示最新版本,例如 “Download Python 3.11.5”)
-
运行下载好的安装程序(.exe 文件)
-
重要:在安装程序的第一个界面勾选 “Add Python to PATH”。这一步非常关键——它允许你在任意命令提示符中运行 Python。
如果忘记勾选会怎样:如果没有勾选 “Add Python to PATH”,你将无法在命令行中运行 Python,并会看到类似
'python' is not recognized as an internal or external command的错误。如果发生这种情况,你要么重新安装 Python(这次勾选该选项),要么手动将 Python 加入 PATH——对初学者来说,后者更复杂。 -
点击 “Install Now”,等待安装完成
-
打开一个新的命令提示符,通过输入以下命令验证安装:
python --version你应该会看到刚刚安装的版本号。
macOS 安装:
-
点击最新版本的 “Download Python” 按钮
-
打开下载的 .pkg 文件,按照安装向导操作
-
打开终端,通过输入以下命令验证安装:
python3 --versionLinux 安装:
大多数 Linux 发行版会自带 Python 3,如果需要安装或更新:
对于 Ubuntu/Debian 系列系统:
sudo apt update
sudo apt install python3对于 Fedora/Red Hat 系列系统:
sudo dnf install python3通过下面命令验证:
python3 --version1.2.3)运行 Python 解释器
安装完成后,你可以直接在命令行或终端中运行 Python 解释器。解释器是执行 Python 代码的程序。直接运行解释器会打开交互式命令行(REPL),我们会在下一节详细介绍。这和运行脚本文件不同,脚本文件会在 1.4 节中讲解。
在 Windows 上:
打开命令提示符,输入:
python在 macOS 和 Linux 上:
打开终端,输入:
python3你应该会看到类似下面的内容:
Python 3.11.5 (main, Sep 11 2023, 13:54:46) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>>>> 提示符表示 Python 已经准备好接收你的命令。这被称为 Python 交互式命令行(Python interactive shell) 或 REPL(Read-Eval-Print Loop),我们会在下一节详细介绍。
要退出解释器,你可以:
- 输入
exit()并回车 - 输入
quit()并回车 - 按
Ctrl + D(在 macOS/Linux 上)或按Ctrl + Z然后回车(在 Windows 上)
恭喜!你已成功安装 Python,并验证了解释器可以工作。现在可以开始编写 Python 代码了。
1.3)使用 Python 交互式命令行(REPL)
Python 的交互式命令行通常被称为 REPL(Read-Eval-Print Loop),它是 Python 在学习和实验时最有用的功能之一。它允许你输入 Python 代码并立即看到结果,非常适合尝试新概念、测试小段代码以及探索 Python 的各种能力。
1.3.1)什么是 REPL?
Python 的交互式命令行,通常被称为 REPL(Read-Eval-Print Loop),是 Python 在学习和实验时最有用的功能之一。REPL 也被称为 Python 交互式命令行(Python interactive shell),或简 simply 的 交互式解释器(interactive interpreter)——这些术语都指同一件事:带有 >>> 提示符的地方,你可以在这里输入 Python 代码并立即看到结果。
REPL 的含义是:
- Read(读取):Python 读取你输入的代码
- Eval(求值):Python 对这段代码求值(执行)
- Print(打印):Python 打印结果
- Loop(循环):Python 回到读取更多代码的状态
这个循环会一直持续,直到你退出 REPL。它就像你在和 Python 对话——你给出一条指令,它给出回应,然后你可以立即根据回应再给出下一条指令。
1.3.2)启动与使用 REPL
要启动 REPL,像上一节那样打开命令行或终端,并在 Windows 上输入 python,或在 macOS/Linux 上输入 python3。
看到 >>> 提示符后,就可以开始输入 Python 代码了。我们试几个基础示例:
简单算术:
>>> 5 + 3
8
>>> 10 * 2
20
>>> 15 / 3
5.0注意,在 REPL 中你不需要使用 print()——Python 会自动显示每个表达式的结果。这是 REPL 的便利之一。
处理文本:
>>> "Hello, World!"
'Hello, World!'
>>> "Python" + " is " + "great"
'Python is great'当你只输入一个字符串(带引号的文本)时,Python 会连同引号一起显示——这是 Python 表示字符串的方式。如果你想显示不带引号的文本,就使用 print() 函数:
>>> print("Hello, World!")
Hello, World!注意差别:只输入字符串时会带引号(Python 的表示形式),而 print() 会显示不带引号的文本(实际输出)。
把值存入变量:
直接输入数值对快速测试很有用,但你通常会希望把值存到变量(variable)中——也就是带名字的数据容器,可以在程序中复用。
>>> name = "Alice"
>>> name
'Alice'
>>> age = 25
>>> age
25当你给变量赋值(例如 name = "Alice")时,Python 不会打印任何内容。但当你只输入变量名时,Python 会显示它的值。
把 Python 当计算器用:
>>> 2 + 2
4
>>> (10 + 5) * 2
30
>>> 100 / 4
25.0
>>> 7 % 3
1REPL 非常适合进行快速计算和测试数学表达式。
1.3.3)在 REPL 中输入多行代码
有时你需要编写跨多行的代码,比如函数定义。REPL 通过改变提示符很好地处理这种情况。当你开始多行语句时,提示符会从 >>> 变为 ...,表示 Python 正在等待你完成该语句。
下面是一个使用函数的简单示例(注意:我们会在第 19 章详细学习函数,这个示例只是展示 REPL 如何通过 ... 继续提示来处理多行输入):
>>> def greet():
... print("Hello!")
...
>>> greet()
Hello!输入第一行并回车后,提示符变为 ...。你输入缩进的下一行,回车,然后在空行上再按一次回车,Python 就会执行这段代码。
1.3.4)访问之前输入的命令
REPL 会保存你输入的命令历史。你可以使用键盘上的上下方向键浏览历史命令:
- 上方向键:显示上一条命令
- 下方向键:在你回到较早命令后,显示下一条命令
当你想稍作修改并重新运行某条命令,或者想回顾之前输入过什么代码时,这个功能非常有用。
1.3.5)在 REPL 中获取帮助
Python 的 REPL 内置了帮助功能。你可以直接获取关于 Python 对象、函数(functions)和模块(modules)的信息。
当你在探索 Python 并想了解可用功能时,这些帮助功能非常有用。例如,如果你在处理字符串并想知道有哪些可用方法,dir(str) 会显示所有选项。随着你在本书中的学习不断深入,你会发现这些工具对你进行独立探索越来越有价值。
>>> help()这会进入帮助系统。你可以输入想获取帮助的名称,或输入 quit 退出帮助系统。
你也可以直接对具体的内容获取帮助:
>>> help(print)这会显示 print() 函数的文档。按 q 退出帮助界面。
另一个很有用的函数是 dir(),它会列出某个对象的所有属性和方法。(注意:属性和方法是对象可用的特性和行为——我们会在第 43 章更详细地学习这些内容。我们还会在第 22 章学习如何导入模块。这个示例展示的是 REPL 如何帮助你探索 Python 的能力。)
>>> dir(str)这会显示字符串对象所有可用的方法。
1.3.6)REPL 最适用的场景
REPL 在以下方面表现突出:
-
学习与探索:当你在学习新概念时,REPL 让你不必创建文件就能立即开始实验。
-
测试小段代码:在把代码加入程序之前,你可以先在 REPL 中测试,确保它按预期工作。
-
快速计算:REPL 是一个随时可用的强大计算器。
-
调试:当程序无法正常工作时,你可以用 REPL 单独测试代码的各个部分。
-
探索库(libraries):当你在学习一个新库时,可以在 REPL 中导入它,并交互式地尝试它的函数(functions)。
不过,REPL 也有局限。你在 REPL 中写的代码,一旦关闭 REPL 就会消失——没有办法把 REPL 会话保存为一个程序。对于任何你想保留并反复运行的代码,你都需要创建脚本文件,我们会在下一节介绍。
1.3.7)退出 REPL
当你使用完 REPL 后,可以通过多种方式退出:
>>> exit()或者:
>>> quit()或者使用键盘快捷键:
- Windows:按
Ctrl + Z,然后回车 - macOS/Linux:按
Ctrl + D
退出后,你会回到常规的命令提示符或终端。
1.4)创建并运行 Python 脚本文件
REPL 非常适合实验和快速测试,但如果你想保存代码并在以后再次运行怎么办?如果你想编写一个包含几十行甚至上百行的长程序又该怎么办?针对这些情况,你需要使用脚本文件(script files)——它们是包含 Python 代码的永久文件,可以编辑、保存并反复运行。
虽然 REPL 在实验方面非常出色,但大多数 Python 编程工作都是通过编写脚本文件(script files)完成的——这些是包含 Python 代码的文本文件,可以保存、编辑并反复运行。本节你将学习如何创建第一个 Python 脚本,并在命令行中运行它。
1.4.1)什么是 Python 脚本?
Python 脚本(Python script)其实就是一个包含 Python 代码的文本文件,并以 .py 扩展名保存。和在 REPL 中输入的代码不同,脚本文件具有以下特点:
- 是持久的——你可以保存,并在以后再次运行
- 可以很容易地编辑和修改
- 可以包含任意多的代码
- 可以分享给他人
- 可以自动或按计划运行
你可以把脚本文件想象成写下来的菜谱,而 REPL 更像是边做菜边现编菜谱。二者各有用途,但对于任何相对重要的内容,你都会更想用脚本文件。
1.4.2)选择文本编辑器
要创建 Python 脚本,你需要一个文本编辑器。不要使用 Microsoft Word 或 Google Docs 这样的文字处理软件——它们会添加 Python 无法理解的格式。
适合初学者的好选择:
-
IDLE:随 Python 一起提供。简单、为学习设计。
- 在 Windows 上:在开始菜单中搜索 “IDLE”
- 在 macOS/Linux 上:在终端中输入
idle3
-
Visual Studio Code (VS Code):免费、功能强大、广泛用于专业开发。通过扩展提供出色的 Python 支持。
-
PyCharm Community Edition:专门为 Python 设计的全功能 IDE(集成开发环境)。
-
Notepad++(仅限 Windows):轻量、简单。
-
Sublime Text:快速、优雅,对 Python 支持良好。
在本书中,我们会使用适用于任意文本编辑器的简单示例。你可以选择自己觉得最顺手的编辑器。
1.4.3)创建你的第一个 Python 脚本
我们来创建一个简单的 Python 脚本,打印一些问候消息。
步骤 1:创建新文件
打开你选择的文本编辑器,新建一个文件。将其保存为 hello.py,保存到一个你记得住的位置(比如桌面,或一个专门的 Python 项目文件夹)。
重要:.py 扩展名非常关键,它告诉操作系统和文本编辑器这是一个 Python 文件。
步骤 2:编写代码
在文件中输入以下代码:
# hello.py
# My first Python script
print("Hello, World!")
print("Welcome to Python programming!")以 # 开头的行是注释(comments)——是写给人看的说明性文字,Python 会完全忽略它们。注释可以帮助你记住代码的用途,也便于他人理解你的工作。我们会在第 2 章更详细地介绍注释。
步骤 3:保存文件
保存文件。确认文件名是 hello.py,而不是 hello.py.txt 或其他扩展名。
我们来理解一下这段代码的作用:
print("Hello, World!")告诉 Python 在屏幕上显示文本 "Hello, World!"。print("Welcome to Python programming!")显示另一条消息。
在进入更复杂的脚本之前,我们再看一个示例,用来起到衔接作用:
# greetings.py
# A script with multiple print statements
print("Python is fun!")
print("Let's learn together.")
print("This is exciting!")将其保存为 greetings.py。这个示例使用了三个 print 语句,但还没有使用变量,有助于你在进入更复杂概念之前先熟悉脚本的基本结构。
1.4.4)从命令行运行脚本
现在你已经创建了脚本,接下来我们来运行它。
步骤 1:打开命令行/终端
- Windows:打开命令提示符(Command Prompt)
- macOS/Linux:打开终端(Terminal)
步骤 2:切换到脚本所在位置
使用 cd(change directory,切换目录)命令进入你保存 hello.py 的文件夹。例如,如果你将其保存到桌面:
Windows:
cd DesktopmacOS/Linux:
cd ~/Desktop如果在尝试运行脚本时收到 “No such file or directory” 之类的错误,说明你很可能不在正确的文件夹中。请使用 cd 命令切换到保存脚本的位置。
为了确认自己在正确位置,你可以列出当前目录中的文件:
Windows:
dirmacOS/Linux:
ls你应该能在列表中看到 hello.py。
步骤 3:运行脚本
Windows:
python hello.pymacOS/Linux:
python3 hello.py你应该会看到输出:
Hello, World!
Welcome to Python programming!恭喜!你刚刚创建并运行了自己的第一个 Python 脚本。
1.4.5)理解脚本的执行过程
当你运行一个 Python 脚本时,大致会经历以下过程:
- 你输入命令来运行脚本
- 操作系统启动 Python 解释器
- 解释器读取整个脚本文件
- 解释器检查是否有语法错误(也就是你写代码的方式是否有问题)
- 如果有错误,它会显示错误信息并停止
- 如果没有错误,它会从上到下逐行执行你的代码
- 所有输出(来自
print()语句)都会显示出来 - 当脚本执行完毕后,控制权返回到命令行
1.4.6)一个更复杂的示例
我们来创建一个稍微更复杂的脚本,展示多个概念。首先,我们增加一个中间示例,更温和地引入变量:
# simple_variable.py
# Using a variable for the first time
message = "Hello, Python!"
print(message)输出:
Hello, Python!这个示例在只使用 print 语句和更复杂的示例之间起到过渡作用。现在我们来看一个包含多个变量的脚本:
# student_info.py
# A script that uses variables and multiple print statements
name = "Alice"
age = 25
city = "New York"
print("Student Information")
print("-------------------")
print("Name:", name)
print("Age:", age)
print("City:", city)将其保存为 student_info.py 并运行:
Windows:
python student_info.pymacOS/Linux:
python3 student_info.py输出:
Student Information
-------------------
Name: Alice
Age: 25
City: New York这个脚本展示了:
- 创建变量(我们会在第 3 章更详细地学习变量)
- 使用多个
print()语句 - 同时打印字面量文本和变量值
1.4.7)脚本文件的一些最佳实践
即使在现在这个阶段,养成一些习惯也是很有帮助的:
-
使用有描述性的文件名:根据脚本的功能来命名文件。
student_info.py要比test.py或program1.py更好,因为六个月后当你在一堆文件中看到它时,仍然会记得它是做什么的。 -
保持脚本有序管理:为你的 Python 项目创建一个专门的文件夹。不要把脚本散落在电脑各处。这样更容易找到你的作品,也能保持文件整洁。
-
添加注释:在每个脚本开头用注释简单说明它的作用。这有助于你之后回顾,也能帮助别人理解你的代码。
-
一个脚本完成一个目的:每个脚本最好只完成一件主要的事情。不要把多个彼此无关的任务塞进一个文件,这会让代码更易于理解和维护。
-
频繁测试:在编写脚本时要经常运行。不要等写完 100 行再测试——每写几行就测试一次。这有助于你在错误还容易修复时尽早发现它们。
1.5)初识错误与回溯信息(tracebacks)
错误是编程中再正常不过的一部分。从初学者到专家,每个程序员都会经常遇到错误。学会阅读和理解错误信息是非常关键的技能,它会帮助你快速修复问题,并让你成为更自信的程序员。
1.5.1)错误的类型
Python 将错误主要分为两大类:
语法错误(Syntax Errors):你在书写代码方式上的错误——违反了 Python 的语法规则。Python 会在运行代码之前就检测出这类错误。可以把语法错误类比为写作中的语法错误——Python 根本无法理解你想说什么。
异常(Exceptions):在代码运行时发生的错误。语法是正确的,但执行过程中出了问题。异常有点像运行期的问题——Python 理解了你的指令,但无法执行。
下面我们通过示例来分别看看这两类错误。
1.5.2)语法错误(Syntax Errors)
当你写出的代码不符合 Python 规则时,就会出现语法错误(syntax error)。Python 完全无法开始运行你的代码,因为它看不懂你写的是什么。
示例 1:缺少冒号
创建一个名为 syntax_error1.py 的文件:
# syntax_error1.py
# This code has a syntax error
if 5 > 3
print("Five is greater than three")当你尝试运行:
python syntax_error1.py你会看到:
File "syntax_error1.py", line 4
if 5 > 3
^
SyntaxError: expected ':'Python 告诉了你几件事情:
- 哪个文件有问题:
syntax_error1.py - 哪一行有问题:第 4 行
- 该行的什么位置有问题:
^指向具体位置 - 错误类型:
SyntaxError - 有用的描述:
expected ':'
问题在于:在 Python 中,if 语句必须以冒号(:)结尾。正确的代码是:
# syntax_error1_fixed.py
# Fixed version
if 5 > 3:
print("Five is greater than three")输出:
Five is greater than three示例 2:引号不匹配
# syntax_error2.py
# Another syntax error example
message = "Hello, World!'
print(message)运行会得到:
File "syntax_error2.py", line 4
message = "Hello, World!'
^
SyntaxError: unterminated string literal (detected at line 4)问题在于字符串用双引号(")开始,却用单引号(')结束。Python 要求引号匹配。可以通过使用匹配的引号来修复:
# syntax_error2_fixed.py
# Fixed version
message = "Hello, World!"
print(message)输出:
Hello, World!1.5.3)运行期异常(Runtime Exceptions)
当你的代码在语法上是正确的,但执行过程中出了问题时,就会发生运行期异常(runtime exceptions)(通常简称为 “exceptions”)。
示例 1:NameError
# name_error.py
# This code will cause a NameError
print(greeting)当你运行:
python name_error.py你会看到:
Traceback (most recent call last):
File "name_error.py", line 4, in <module>
print(greeting)
^^^^^^^^
NameError: name 'greeting' is not defined这被称为回溯(traceback)。我们来拆解一下:
- "Traceback (most recent call last):" 表示接下来是错误发生位置的回溯信息。
- 文件和行号信息:
File "name_error.py", line 4, in <module>告诉你是哪个文件中的哪一行导致了错误。 - 有问题的代码行:
print(greeting)展示出错的确切代码行。 - 错误类型:
NameError告诉你发生了哪种错误。 - 错误描述:
name 'greeting' is not defined解释了问题——你在尝试使用一个尚未定义的变量。
要修复它,你需要在使用变量前先定义它:
# name_error_fixed.py
# Fixed version
greeting = "Hello!"
print(greeting)输出:
Hello!示例 2:TypeError
# type_error.py
# This code will cause a TypeError
number = 5
text = "The number is "
result = text + number
print(result)运行会产生:
Traceback (most recent call last):
File "type_error.py", line 6, in <module>
result = text + number
~~~~~^~~~~~~~
TypeError: can only concatenate str (not "int") to str错误信息告诉你,不能直接把字符串(string)和整数(integer)相加(连接)。Python 不知道你是想做数学加法还是字符串拼接。
要修复它,需要把数字转换为字符串:
# type_error_fixed.py
# Fixed version
number = 5
text = "The number is "
result = text + str(number)
print(result)输出:
The number is 5示例 3:ZeroDivisionError
如果你尝试除以零会发生什么?
# zero_division.py
# This code will cause a ZeroDivisionError
result = 10 / 0
print(result)运行结果为:
Traceback (most recent call last):
File "zero_division.py", line 4, in <module>
result = 10 / 0
~~~^~~
ZeroDivisionError: division by zero这个错误很直观:你不能除以零。数学上没有定义,所以 Python 会抛出错误。
1.5.4)高效阅读回溯信息
当你遇到回溯信息时,应当从下往上阅读。我们之所以从下往上读,是因为最底部那一行显示出了什么错误(错误类型和错误信息),而其上的行展示了导致这个错误的函数调用序列。对于我们目前这种简单程序,底部那一行通常已经包含你需要知道的一切。
- 从底部开始:首先查看错误类型和错误信息。
- 理解错误:Python 在告诉你具体发生了什么问题?
- 找到位置:查看错误发生的文件和行号。
- 检查那一行代码:在文件中找到对应该行并查看。
- 必要时向前追踪:有时问题实际上出在 Python 指出的那一行的前一行。
1.5.5)初学者常见错误
下面是你在学习 Python 过程中很可能遇到的一些错误:
缩进错误(Indentation Errors):
Python 使用缩进(行首的空格或制表符)来定义代码块。不正确的缩进会导致错误:
# indentation_error.py
# Incorrect indentation
print("First line")
print("Second line") # This line is incorrectly indented错误信息:
File "indentation_error.py", line 5
print("Second line")
^
IndentationError: unexpected indent拼写错误:
Python 区分大小写。Print 和 print 不是一回事:
# spelling_error.py
# Incorrect capitalization
Print("Hello") # Should be print, not Print错误信息:
Traceback (most recent call last):
File "spelling_error.py", line 4, in <module>
Print("Hello")
^^^^^
NameError: name 'Print' is not defined缺少括号:
在 Python 3 中,print 需要括号:
# missing_parentheses.py
# Missing parentheses
print "Hello" # Should be print("Hello")错误信息:
File "missing_parentheses.py", line 4
print "Hello"
^^^^^^^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?注意 Python 的错误信息有多贴心——它甚至给出了修正建议!
1.5.6)处理错误的策略
当你遇到错误时:
-
不要慌张:错误是正常的。每个程序员都会经常看到它们。
-
仔细阅读错误信息:Python 的错误信息通常很有帮助。它们会告诉你哪里出了问题,以及问题所在的位置。
-
检查行号:转到 Python 指出的行,看看那里是否有问题。
-
看看附近的行:有时错误实际上出在 Python 指出的前一行。
-
检查常见错误:缺少冒号、引号不匹配、缩进不正确以及拼写错误都是非常常见的问题。
-
小步修改并测试:一次只修改一个地方,然后测试。
-
使用 REPL:如果你对某段代码拿不准,可以先在 REPL 中测试。
-
搜索错误信息:如果你不理解某条错误信息,可以把它复制到网上搜索,你往往会找到解释和解决方案。
1.5.7)一个完整的错误与修复示例
我们来看一个包含多个错误的脚本,并一步步修复。这个程序的设计目的是展示一位学生的信息,并计算 ta 在 10 年后的年龄:
原始版本(包含错误):
# buggy_student.py
# This program has several errors
student_name = "Alice
student_age = 25
print("Name:", student_name)
print("Age:" student_age)
print("In 10 years, you will be", student_age + "10")运行后会产生多个错误。我们逐个修复:
错误 1:字符串没有正确结束
File "buggy_student.py", line 4
student_name = "Alice
^
SyntaxError: unterminated string literal (detected at line 4)修复:补上结束引号:
student_name = "Alice"修复错误 1 后,会出现错误 2:缺少逗号
File "buggy_student.py", line 8
print("Age:" student_age)
^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?修复:在字符串和变量之间添加逗号:
print("Age:", student_age)修复错误 2 后,会出现错误 3:类型错误
Traceback (most recent call last):
File "buggy_student.py", line 9, in <module>
print("In 10 years, you will be", student_age + "10")
~~~~~~~~~~~~^~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'str'修复:把 "10" 改为整数:
print("In 10 years, you will be", student_age + 10)最终修正版:
# buggy_student_fixed.py
# Fixed version of the program
student_name = "Alice"
student_age = 25
print("Name:", student_name)
print("Age:", student_age)
print("In 10 years, you will be", student_age + 10)输出:
Name: Alice
Age: 25
In 10 years, you will be 35这个示例表明,修复错误往往是一个迭代过程。你修复一个错误,重新运行代码,然后发现下一个错误。这完全是正常的。
1.6)何时使用交互式命令行,何时使用脚本文件
既然你已经学习了 REPL 和脚本文件这两种方式,可能会好奇:什么时候该用哪一种?二者都是非常有价值的工具,有经验的 Python 程序员会经常同时使用。理解什么时候使用哪一种,会让你更高效。
1.6.1)在以下情况使用交互式命令行(REPL):
1. 学习新概念时
当你在学习新知识时,REPL 能提供即时反馈:
>>> # Testing string methods
>>> text = "hello world"
>>> text.upper()
'HELLO WORLD'
>>> text.title()
'Hello World'
>>> text.capitalize()
'Hello world'你可以尝试不同的方法并立即看到结果,无需创建文件。
2. 测试小段代码时
在将代码加入程序之前,先在 REPL 中测试:
>>> # Testing a calculation
>>> price = 19.99
>>> quantity = 3
>>> total = price * quantity
>>> total
59.97
>>> # Looks good, now I can add this to my script3. 进行快速计算时
REPL 随时可以作为计算器使用:
>>> # How many seconds in a day?
>>> 24 * 60 * 60
86400
>>> # What's 15% of 250?
>>> 250 * 0.15
37.54. 调试时
当脚本不工作时,可以使用 REPL 测试代码的各个部分:
>>> # My script isn't working. Let me test this part:
>>> numbers = [1, 2, 3, 4, 5]
>>> sum(numbers) / len(numbers)
3.0
>>> # This works, so the problem must be elsewhere注意:我们会在第 13 章学习列表(lists)。这个示例展示的是 REPL 如何帮助你测试代码片段。
1.6.2)在以下情况使用脚本文件:
1. 编写你想保留的程序时
任何你想保存并重复运行的内容都应该放在脚本文件中:
# temperature_converter.py
# A program to convert Fahrenheit to Celsius
fahrenheit = 98.6
celsius = (fahrenheit - 32) * 5/9
print("Temperature:", fahrenheit, "°F is", round(celsius, 1), "°C")输出:
Temperature: 98.6 °F is 37.0 °C你可以在需要时随时运行这个脚本,也可以在以后对它进行修改。
2. 编写多行程序时
尽管你可以在 REPL 中编写多行代码,但对于稍微大一点的程序来说会比较笨拙。这种情况下应使用脚本文件:
# grade_calculator.py
# Calculate final grade from multiple scores
homework = 85
midterm = 78
final = 92
# Calculate weighted average
final_grade = (homework * 0.3) + (midterm * 0.3) + (final * 0.4)
print("Final Grade:", final_grade)输出:
Final Grade: 85.33. 与他人分享代码时
脚本文件可以轻松分享,而 REPL 会话则无法:
# greeting.py
# A simple greeting program
name = input("What is your name? ")
print("Hello,", name + "! Welcome to Python.")注意:我们会在第 2 章学习 input() 函数。这个示例展示的是脚本如何被分享。
你可以把这个文件发给别人,他们就能在自己的电脑上运行它。
4. 构建可复用工具时
如果你要创建某个会反复使用的内容,就应该把它写成脚本:
# file_counter.py
# Count files in a directory
import os
directory = "." # Current directory
files = [f for f in os.listdir(directory) if os.path.isfile(f)]
print("Number of files:", len(files))注意:我们会在第 22 章学习如何导入模块,在第 34 章学习列表推导式(list comprehensions)。这个示例展示的是脚本如何变成可复用工具。
5. 开发复杂逻辑时
对于包含多个函数(functions)、类(classes)或复杂逻辑的任何内容,应使用脚本文件:
# password_checker.py
# Check password strength
def check_password_strength(password):
"""Check if a password meets basic requirements."""
if len(password) < 8:
return "Too short"
if not any(c.isupper() for c in password):
return "Needs uppercase letter"
if not any(c.isdigit() for c in password):
return "Needs number"
return "Strong password"
# Test the function
test_password = "MyPass123"
result = check_password_strength(test_password)
print("Password '" + test_password + "':", result)输出:
Password 'MyPass123': Strong password注意:我们会在第 19 章学习函数(functions)。这个示例展示的是脚本如何处理较复杂的逻辑。
6. 实现自动化任务时
脚本非常适合用于自动化:
# backup_reminder.py
# Remind user to backup files
import datetime
today = datetime.date.today()
day_of_week = today.strftime("%A")
if day_of_week == "Friday":
print("Don't forget to backup your files!")
else:
print("Backup reminder: Next backup on Friday")注意:我们会在第 39 章学习 datetime 模块。这个示例展示的是脚本如何实现任务自动化。
1.6.3)一种实用的工作流
专业的 Python 程序员通常会以互补的方式同时使用 REPL 和脚本文件:
示例工作流:
- 在 REPL 中探索:尝试新概念或测试一个计算
- 在 REPL 中做原型:构建一个小型可工作的版本
- 迁移到脚本中:一旦可行,就把代码放到脚本文件中
- 在脚本中扩展:添加更多功能、错误处理等
- 用 REPL 调试:如果出了问题,就在 REPL 中测试部分代码
- 完善脚本:完成、测试并保存你的程序
1.6.4)一个具体示例
我们来看看这种工作流的实际过程。假设你想编写一个计算圆面积的程序。
步骤 1:在 REPL 中探索
>>> # What's the formula? Area = π * r²
>>> # Let me use a simple approximation for π
>>> 3.14159 * 5 * 5
78.53975
>>> # Looks right!步骤 2:创建脚本
既然你知道它有效,就创建 circle_area.py:
# circle_area.py
# Calculate the area of a circle
radius = 5
pi = 3.14159
area = pi * radius * radius
print("Radius:", radius)
print("Area:", area)输出:
Radius: 5
Area: 78.53975步骤 3:增强脚本
让它可以处理不同的半径:
# circle_area_enhanced.py
# Calculate area for multiple circles
radii = [3, 5, 7, 10]
pi = 3.14159
for radius in radii:
area = pi * radius * radius
print("Circle with radius", radius, "has area", round(area, 2))输出:
Circle with radius 3 has area 28.27
Circle with radius 5 has area 78.54
Circle with radius 7 has area 153.94
Circle with radius 10 has area 314.16注意:我们会在第 11 章学习 for 循环(loops)。在第 2 章,我们会学习如何通过获取用户输入让这个程序变得具有交互性。
这种工作流——先在 REPL 中实验,然后在脚本中正式编写——就是许多 Python 程序的开发方式。
1.6.5)关键要点
REPL 的优势:
- 反馈即时
- 非常适合学习
- 非常适合快速测试
- 非常适合探索
- 不需要管理文件
REPL 的局限:
- 代码不会被保存
- 多行代码操作不够方便
- 不易分享
- 不适合复杂程序
脚本文件的优势:
- 代码会被永久保存
- 易于编辑和修改
- 可以分享给他人
- 适合复杂程序
- 可以被反复运行
- 可以实现自动化
脚本文件的局限:
- 需要创建和管理文件
- 必须运行后才能看到结果
- 对于快速测试来说开销略大
最佳方式是两者结合使用:用 REPL 进行学习、测试和探索,用脚本文件来编写任何你想保留、分享或反复运行的代码。
1.7)本书使用的 Python 版本(以及这为什么重要)
多年以来,Python 有了显著发展,不同版本的行为可能有所不同。理解 Python 版本将帮助你避免困惑,并确保代码按预期工作。
你可能会问,为什么要花时间讨论 Python 版本?原因很简单:你会在网上、教程和文档中接触到各种 Python 代码。理解版本差异有助于你识别哪些代码已经过时,也能在某段代码无法按预期工作时避免困惑。
1.7.1)Python 2 与 Python 3
Python 历史上最重要的分界是 Python 2 和 Python 3 之间的差异。
Python 2 发布于 2000 年,并在许多年里占据主导地位。然而,它存在一些设计问题,如果不破坏现有代码就无法修复。
Python 3 发布于 2008 年,是一次修复这些问题的重大重构。不过,它不向后兼容 Python 2,也就是说,为 Python 2 编写的代码往往无法在 Python 3 中直接运行,除非做出修改。
在很多年里,这两个版本曾并存。然而,Python 2 在 2020 年 1 月 1 日正式停止维护(end-of-life)。这意味着:
- 不再为 Python 2 提供更新或安全补丁
- 所有新的 Python 开发都使用 Python 3
- 所有主要库都已经迁移到 Python 3
- 如今学习 Python 2 并不推荐
本书完全使用 Python 3。所有示例代码都是为 Python 3 编写的,在 Python 2 中可能无法运行。
1.7.2)Python 3 的次版本号
在 Python 3 中,存在多个次版本(minor version),比如 3.6、3.7、3.8、3.9、3.10、3.11、3.12 等。每个次版本都会在保持与之前 Python 3 版本向后兼容的前提下,添加新特性和改进。
本书是为 Python 3.11 及更高版本编写的,但大部分示例在 Python 3.8 及更高版本上都能正常运行。
要检查你当前的 Python 版本:
python --version # Windows
python3 --version # macOS/Linux你应该会看到类似下面的内容:
Python 3.11.5如果你看到的是:
Python 2.7.18说明你正在运行已经过时的 Python 2。请参考 1.2 节中的说明安装 Python 3。
1.7.3)你可能遇到的一些关键差异
如果你在阅读较旧的 Python 教程或网上代码(尤其是 2020 年之前的旧教程和 Stack Overflow 回答)时,可能会看到在 Python 3 中无法运行的语法。下面是最常见的一些差异:
1. print 语句 vs print 函数
Python 2:
print "Hello, World!" # No parenthesesPython 3:
print("Hello, World!") # Parentheses required在 Python 3 中,print 是函数,需要使用括号。这是最明显的差异之一。
2. 除法行为
这些改动的目的,是让 Python 更一致、更安全。例如,把 print 变成函数后,它就可以像其他函数一样使用;而让 / 始终执行浮点除法,则消除了一类常见 bug 的来源。
Python 2:
>>> 5 / 2
2 # Integer division
>>> 5.0 / 2
2.5 # Float divisionPython 3:
>>> 5 / 2
2.5 # Always float division
>>> 5 // 2
2 # Integer division (floor division)在 Python 3 中,/ 始终执行浮点除法。使用 // 表示整数除法(向下取整)。
3. input() 函数
Python 2:
name = raw_input("Enter your name: ") # Returns string
age = input("Enter your age: ") # Evaluates input as Python code (dangerous!)Python 3:
name = input("Enter your name: ") # Always returns string
age = int(input("Enter your age: ")) # Convert to int if needed在 Python 3 中,input() 始终返回字符串,这样更安全,也更一致。
4. 字符串和 Unicode
在处理文本(尤其是非英语文本)时,Python 3 比 Python 2 处理得好得多。Python 3 中所有字符串默认都是 Unicode,这让国际化文本处理更加容易。
1.7.4)各 Python 3 版本中的特性
不同的 Python 3 版本引入了不同的特性。你需要了解的是:
Python 3.6(2016 年 12 月):
- 引入 f-strings,用于字符串格式化(我们会在本书中广泛使用)
# f_string_example.py
name = "Alice"
print("Hello, " + name + "!")输出:
Hello, Alice!注意:我们会在第 6 章学习 f-strings。现在我们使用的是简单的 + 字符串拼接。
Python 3.8(2019 年 10 月):
- 引入海象运算符(walrus operator,
:=),用于赋值表达式(我们会在第 40 章讲解)
Python 3.10(2021 年 10 月):
- 引入结构化模式匹配(structural pattern matching),使用
match和case(我们会在第 12 章讲解)
Python 3.11(2022 年 10 月):
- 错误信息得到显著改进
- 性能提升
- 加强异常处理能力
Python 3.12(2023 年 10 月):
- 进一步提升性能
- 新的类型注解特性
- 改进 f-string 语法
1.7.5)你应该使用哪个版本?
推荐:如果可能,使用 Python 3.11 或更高版本。原因包括:
-
更好的错误信息:Python 3.11 的错误信息有了显著改进,对初学者更友好。
-
更好的性能:Python 3.11 比早期版本运行更快。
-
现代特性:你可以使用所有最新的 Python 特性。
-
更具前瞻性:为 Python 3.11 编写的代码在未来版本中也能正常运行。
不过,只要是 Python 3.8 或更高版本,都足以用于本书的学习。核心概念在不同版本中是相同的。
1.7.6)检查某个特性的可用性
如果你使用的是较旧的 Python 版本,遇到某些代码无法运行,可以检查一下该特性是在哪个版本中引入的。
例如,如果你使用的是 Python 3.5 或更早版本,就可能需要使用较旧的字符串格式化方式:
# format_example.py
# Works in all Python 3 versions
name = "Alice"
print("Hello, {}!".format(name))输出:
Hello, Alice!1.7.7)如何保持与时俱进
Python 大约每年发布一个新的次版本。你不需要每次都立刻升级,但保持相对“新一点”的版本是有好处的:
- 每隔几个月检查一次更新
- 阅读发布说明,了解新增特性
- 在方便的时候升级,尤其是涉及安全更新时
- 升级后测试你的代码,确保兼容性
你可以在 https://www.python.org/ 找到 Python 的发布版本和文档。
1.7.8)本书中的版本兼容性说明
在本书中:
- 所有示例代码都能在 Python 3.11+ 上运行
- 大多数示例在 Python 3.8+ 上也能运行
- 对特定版本才有的特性会明确说明(例如,“此功能需要 Python 3.10+”)
- 在合适的情况下,会为旧版本提供替代方法
因此,当你在本书中看到某段代码时,可以放心地在 Python 3.11 或更高版本中输入并运行,预期结果会与书中展示的一致。
1.7.9)关于你在网上可能遇到的 Python 2 代码的说明
当你在网上搜索 Python 相关帮助时,可能会遇到 Python 2 代码。下面是识别它的一些线索:
典型的 Python 2 代码特征:
print不带括号:print "Hello"- 使用
raw_input()函数 - 除法得到整数结果:
5 / 2等于2 - 使用旧式字符串格式化:
"Hello %s" % name - 注释中提到 “Python 2” 或版本号为 2.x
你应该怎么做:
- 寻找对应的 Python 3 写法
- 在搜索关键字中加入 “python 3”
- 注意发布时间——2020 年之前的内容很可能是 Python 2
- 使用官方 Python 3 文档:https://docs.python.org/3/
恭喜你!你已经完成了第 1 章,迈出了使用 Python 的第一步。现在你已经了解了:
- Python 是什么,以及它是如何工作的
- 如何安装 Python 并运行解释器
- 如何使用 Python 交互式命令行(REPL)进行实验
- 如何创建并运行 Python 脚本文件
- 如何阅读并理解错误信息和回溯(tracebacks)
- 何时使用 REPL,何时使用脚本文件
- 应该使用哪个 Python 版本,以及这为什么重要
你已经准备好进入第 2 章。在下一章中,你将编写第一个完整的 Python 程序,详细学习 print() 函数,并开始处理用户输入。本章打下的基础将支撑你后续学习的所有内容。