Python 零基础入门教程

写给第一次接触编程的你。本教程假设你完全没有写过代码,也从零开始,一步一步来。
我们会在第 2 章帮你把电脑上的 Python 环境搭好,之后每一章都有可以直接复制运行的小例子,以及「动手试试」的小练习。

阅读建议:不要跳着看,也不要只"看"不"打"。编程和做实验一样,看一百遍不如亲手敲一遍。每看到一个代码块,就照着敲到电脑里运行一下。


目录

  1. Python 是什么,能做什么,为什么你该学
  2. 安装与环境搭建
  3. 第一个程序
  4. 变量与基本数据类型
  5. 运算符
  6. 输入输出
  7. 控制流:if / elif / else
  8. 循环:for 与 while
  9. 字符串进阶
  10. 列表 list
  11. 元组、字典、集合
  12. 函数
  13. 模块与导入
  14. 文件读写
  15. 错误与异常
  16. 面向对象入门(可选)
  17. 综合小项目:处理一组实验数据
  18. 新手常见坑清单
  19. 下一步学什么 + 推荐资源

1. Python 是什么,能做什么,为什么你该学

1.1 它是什么?

Python 是一种"编程语言"。 编程语言,就是人类用来给电脑下指令的一套规则。就像你跟外国人说话要用英语,你要让电脑干活,就得用它能听懂的语言。Python 就是其中一种,而且以"好读、好写、好学"著称。

你写一段文字(叫代码,code),让电脑按顺序执行,电脑就会帮你做事情:算数、整理数据、批量改文件、画图、抓取网页……凡是重复、量大、需要精确的事情,都可以交给它。

1.2 它长什么样?

下面是一小段 Python 代码,就算你现在看不懂也没关系,先感受一下"原来长这样":

# 这是一行注释,电脑会忽略它,是写给人看的
elements = ["H", "O", "C", "N"]          # 把几个元素符号装进一个"列表"
for e in elements:                        # 逐个拿出每个元素
    print("这个元素是:" + e)             # 打印出来

运行后,电脑会一行一行地打印出每个元素符号。

1.3 它能做什么

  • 算数:把一堆实验数据加起来、求平均、找最大最小值。
  • 处理文本:批量重命名文件、从几万行日志里找关键词。
  • 处理数据:整理表格、清洗数据、画统计图。
  • 自动化:定时下载文献、批量格式转换、自动发提醒。
  • 科学计算:配合 NumPy、SciPy、Matplotlib 等工具做计算和绘图(本教程系列里有专门讲这些的)。
  • 做网站、做游戏、做人工智能:Python 也是这些领域的主流语言之一。

1.4 为什么化学 / 科研的人需要学

做科研,尤其是计算化学相关领域,每天都会遇到这些场景:

  • 一个数据文件里有几百上千个数值,要算平均值、标准差、找异常点——用 Excel 也能做,但 Python 可以一键、可重复、可留痕地完成,下次换一批数据直接再跑一遍。
  • 要批量处理几十上百个分子文件、提取能量值、改输入文件——手动一个个点,既慢又容易错。
  • 要用 VASP、ASE、RDKit、pymatgen 这些科研工具——它们几乎都用 Python 作为"操作语言"。学会 Python,你才能真正驾驭这些工具。

简单说:Python 是你科研路上的"计算器 + 秘书 + 助手",而且它免费、跨平台、资料最多。

1.5 你不需要什么

  • 你不需要数学特别好,会加减乘除就行。
  • 你不需要英语特别好,虽然代码里会出现英文单词,但就那么几十个常用的,见多了就熟了。
  • 你不需要会装逼的电脑技能,会打开文件夹、会打字就行。

好,下面我们动手,把环境装好。


2. 安装与环境搭建

这一章以我的实际运行环境为例:Windows + Miniconda + Python 3.14 + VS Code。

先解释几个名词(都用人话):

  • Miniconda:一个"装 Python 和管理环境"的工具。它最厉害的地方是能给你创建独立的虚拟环境,让不同项目的 Python 互不干扰。
  • 虚拟环境(conda 环境):你可以理解成"一间独立的房间"。每个房间里装一套 Python 和一套工具,房间之间互不影响。这样你搞科研装 A 库,学基础装 B 库,不会打架。
  • VS Code:一个写代码用的"编辑器"(就像写文档用 Word,写代码用 VS Code),免费、好用、有中文界面。
  • 交互式 Python(REPL):一种"输入一句、立刻回一句"的对话式用法,后面会讲。

2.1 第一步:安装 Miniconda

  1. 打开浏览器,搜索 Miniconda,或直接访问官网下载页 https://docs.conda.io/en/latest/miniconda.html。
  2. 选择 Windows 版本(通常是一个 .exe 安装包,选 64-bit)。
  3. 双击运行安装包,一路点"下一步"(Next)即可。注意一个选项:"Add Miniconda3 to my PATH environment variable"(加入环境变量)默认可能不勾选,建议勾选,这样后面在任何终端都能用 conda 命令。如果装的时候没勾也没关系,可以用它自带的 "Anaconda Prompt" 来操作。
  4. 装完后,在 Windows 开始菜单搜索 "Anaconda Prompt"(或 "Miniconda Prompt")并打开——这是一个黑色窗口(叫终端 / 命令行),我们后面要在这里输入命令。

2.2 第二步:确认安装成功

在终端里输入下面这行,然后回车(输入命令后都按回车执行):

conda --version

如果显示类似 conda 24.x.x 这样的版本号,说明装好了。

2.3 第三步:创建一个虚拟环境(装 Python 3.14)

在终端里输入下面这条命令,创建一个名叫 py314 的环境,并指定 Python 版本为 3.14:

conda create -n py314 python=3.14 -y

解释一下:

  • conda create:让 conda 创建东西。
  • -n py314:给新环境起名叫 py314(名字随便取,好记就行)。
  • python=3.14:指定这个环境里装 Python 3.14。
  • -y:意思是"中途如果问你是否继续,自动回答 yes",省得手动确认。

它会联网下载并安装,等它跑完(可能几分钟)。

2.4 第四步:激活(进入)这个环境

conda activate py314

激活成功后,你会看到命令行的最前面出现了 (py314),像这样:

(py314) C:\Users\你的用户名>

这表示你现在已经"进入"了 py314 这个房间。以后每次写代码前,都要先执行 conda activate py314 进入环境。

验证一下 Python 版本:

python --version

应该显示 Python 3.14.x。恭喜,Python 装好了。

退出环境用 conda deactivate。查看你有哪些环境用 conda env list。

2.5 第五步:安装 VS Code

  1. 搜索 VS Code,到官网 https://code.visualstudio.com/ 下载 Windows 版,双击安装(一路默认即可)。
  2. 装好后打开 VS Code。

2.6 第六步:给 VS Code 装上 Python 扩展

  1. 在 VS Code 左侧竖排图标栏,点最下面的扩展图标(四个小方块拼成的图标)。
  2. 在搜索框输入 Python,找到微软官方的 "Python" 扩展(作者是 Microsoft),点 Install(安装)。
  3. 装好后,VS Code 就能识别 Python 代码、自动补全、一键运行了。

2.7 第七步:让 VS Code 使用你的 py314 环境

  1. 在 VS Code 里按快捷键 Ctrl + Shift + P,会弹出命令面板。
  2. 输入并选择 Python: Select Interpreter(选择解释器)。
  3. 在列表里找到 py314(或者路径里带 py314 的那个),点它选中。

"解释器"(interpreter)就是"真正执行 Python 代码的程序"。选了 py314,VS Code 就会用你环境里的 Python 3.14 来运行代码。

2.8 第八步:运行你的第一个 .py 文件

  1. 在 VS Code 里按 Ctrl + N 新建文件,按 Ctrl + S 保存,文件名写 hello.py(后缀 .py 表示这是 Python 文件,很重要),保存到一个你找得到的文件夹,比如 D:\code。
  2. 在文件里输入:
print("你好,Python!")
  1. 保存后,点右上角的三角形运行按钮(▶),或者按 Ctrl + F5。
  2. 看下方会弹出"终端"面板,里面显示运行结果:
你好,Python!

如果能看到这行字,说明你的环境完全搭好了,可以正式进入学习了!

2.9 补充:交互式 Python(快速试代码用)

有时候你只想快速试一句代码,不想建文件,可以用"对话模式"。在终端里(先 conda activate py314)输入:

python

会看到 >>> 这样的提示符,这就是交互式环境(英文叫 REPL)。你可以直接输入代码,回车立刻出结果:

>>> 1 + 2
3
>>> print("hi")
hi

想退出,输入 exit() 再回车即可。

本教程里的很多小例子,你都可以在文件里跑,也可以在 >>> 里试。建议先建文件跑,养成好习惯。


3. 第一个程序

3.1 print:让电脑"说"出来

print 是 Python 里最常用的一个功能:把东西显示到屏幕上。print 就是"打印、显示"的意思。

print("你好,化学世界!")
print(42)
print(3.14)

运行结果:

你好,化学世界!
42
3.14

要点:

  • print 后面跟一对圆括号 (),括号里是要显示的内容。
  • 显示文字时,文字要用引号包起来(单引号 '...' 或双引号 "..." 都可以,成对用就行)。
  • 显示数字时,直接写数字,不用引号。

3.2 一次显示多个东西

用逗号隔开,print 会把它们依次显示出来,中间自动加一个空格:

print("氢", "氦", "锂", "铍")     # 会显示:氢 氦 锂 铍
print("原子序数:", 1)            # 会显示:原子序数: 1

3.3 注释:写给"人"看,电脑不管

代码里,以 # 开头的部分叫注释。注释是写给你自己(或同事)看的说明文字,电脑会直接跳过它。

# 这个程序会打印一个元素符号
print("H")        # 这一行后面的 # 也是注释

写注释是好习惯,尤其过几天你自己回头看代码时,注释能帮你快速想起"我当时在干嘛"。

动手试试

  1. 用 print 显示你的名字。
  2. 用 print 显示一个元素符号和它的原子序数(比如 O 和 8)。
  3. 写一行注释,说明你的代码在做什么。

参考答案(思路):

print("XXX")                 # 练习1:显示你的名字
print("O", 8)                    # 练习2:显示元素符号和原子序数
# 这里写一句说明这个程序在干什么

4. 变量与基本数据类型

4.1 变量:给东西起个名字存起来

变量(variable) 就是"一个有名字的盒子",你可以往盒子里放东西,之后用名字就能把这个东西拿出来用。

element = "H"          # 建一个叫 element 的变量,里面放了字符串 "H"
atomic_number = 1      # 建一个叫 atomic_number 的变量,里面放了数字 1
print(element)         # 打印出 element 里存的东西 -> H
print(atomic_number)   # -> 1
  • = 在这里叫赋值,意思是"把右边的东西放到左边的盒子里"。读作"把 ... 赋给 ...",不是"等于"!这点新手特别容易混,后面第 18 章专门讲。
  • 变量的名字你可以自己起,但有个规则:只能由字母、数字、下划线 _ 组成,且不能以数字开头。比如 mass1 可以,1mass 不行;原子量 这种中文名其实也能用,但强烈建议用英文或拼音,兼容性更好。
  • 变量名是区分大小写的:Mass 和 mass 是两个不同的变量。
mass = 1.008        # 氢的相对原子质量(粗略值)
print(mass)         # 1.008
mass = 4.0          # 盒子里的东西可以换
print(mass)         # 4.0

4.2 四种最基础的数据类型

数据类型 就是"东西的种类"。电脑对不同种类的东西,处理方式不一样。最开始你只需要认识这几种:

类型英文说明例子
整数int不带小数点的数1, -3, 100
浮点数float带小数点的数("浮点"就是"小数点会浮动"的意思,别被名字吓到)3.14, 1.008, -0.5
字符串str一串文字,用引号包起来"H2O", "hello"
布尔值bool只有两个取值:真 / 假True, False
n = 8              # int 整数
weight = 15.999    # float 浮点数(氧的相对原子质量)
formula = "H2O"    # str 字符串
is_gas = True      # bool 布尔值(水是气体吗?False 才对吧,这里只做演示)
print(n, weight, formula, is_gas)

注意 True 和 False 首字母必须大写,否则会报错。

4.3 用 type() 查看一个东西的类型

print(type(8))          # <class 'int'>
print(type(15.999))     # <class 'float'>
print(type("H2O"))      # <class 'str'>
print(type(True))       # <class 'bool'>

<class '...'> 里的就是类型名。看不懂没关系,记住 type() 能帮你看"这到底是个啥"。

4.4 类型转换:把一种类型变成另一种

这是科研数据处理里极其常用的操作。比如从文件读出来的数字常常是字符串 "3.14",你要拿它做计算,就得先转成数字。

a = "42"          # 这是一个字符串,不是数字
b = int(a)        # int(...) 把它转成整数 42
print(b + 1)      # 43(字符串没法直接 +1,转成数字才能算)

c = "3.14"
d = float(c)      # 转成浮点数
print(d * 2)      # 6.28

e = 100
f = str(e)        # 数字转成字符串
print("数值是" + f)   # "数值是100"(字符串和字符串才能用 + 拼起来)

反过来,如果转不了,会报错:

int("abc")   # 报错!"abc" 没法变成整数

这个报错我们到第 15 章会知道怎么处理。

动手试试

  1. 建一个变量存你的年龄,用 type() 看它的类型。
  2. 建一个变量存字符串 "100",把它转成整数后加 1,打印结果。
  3. 把整数 7 转成字符串,再用 + 和字符串 "号元素" 拼起来打印。

参考答案:

# 1
age = 22
print(type(age))            # <class 'int'>

# 2
s = "100"
print(int(s) + 1)           # 101

# 3
n = 7
print(str(n) + "号元素")     # 7号元素

5. 运算符

运算符 就是"加、减、比大小、判断真假"这些符号。程序里靠它们做计算和判断。

5.1 算术运算符(加减乘除那些)

符号含义例子结果
+加1 + 23
-减5 - 23
*乘3 * 412
/除(结果永远是浮点数)10 / 42.5
//整除(只取整数部分,向下取)10 // 42
%取余数10 % 42
**乘方2 ** 38

注意:乘是 * 不是 ×,除是 / 不是 ÷,电脑键盘上没有 ×÷ 号。

print(10 / 4)     # 2.5,普通除法,结果是小数
print(10 // 4)    # 2,整除,丢掉小数部分
print(10 % 4)     # 2,10 除以 4 余 2
print(2 ** 10)    # 1024,2 的 10 次方

% 取余特别有用,比如判断一个数是不是偶数:x % 2 == 0(余 0 就是偶数)。

5.2 比较运算符(比大小,结果是 True / False)

符号含义例子结果
==等于3 == 3True
!=不等于3 != 3False
>大于5 > 3True
<小于5 < 3False
>=大于等于5 >= 5True
<=小于等于4 <= 3False
print(3 == 3)    # True
print(3 == 4)    # False
print(3 != 4)    # True

特别注意:判断"等于"要用两个等号 ==,单个 = 是赋值,不是比较。这是新手第一大坑,第 18 章再强调。

5.3 逻辑运算符(把多个判断组合起来)

  • and:两边都真,结果才真("并且")。
  • or:两边只要有一个真,结果就真("或者")。
  • not:取反(把真变假、假变真)。
print(3 > 2 and 5 > 4)    # True,两个都对
print(3 > 2 and 5 > 10)   # False,第二个不对
print(3 > 10 or 5 > 4)    # True,第二个对就行
print(not (3 > 2))        # False,把"对"变成"错"

5.4 赋值运算符(简写)

前面见过 =。还有几种"边算边存"的简写:

x = 10
x = x + 5      # x 变成 15(先算右边的 x+5=15,再存回 x)
print(x)       # 15

x += 5         # 和 x = x + 5 完全等价,简写
print(x)       # 20

x -= 3         # x = x - 3
x *= 2         # x = x * 2
x /= 4         # x = x / 4

动手试试

  1. 计算 7 的 3 次方。
  2. 判断 2024 是不是偶数(提示:2024 % 2 == 0)。
  3. 设 temp = 25,写一个逻辑表达式,判断温度是否在 0 到 100 之间(用 and)。
  4. 用 // 和 %,把 100 秒换算成"分钟和剩余秒"。

参考答案:

# 1
print(7 ** 3)              # 343

# 2
print(2024 % 2 == 0)       # True

# 3
temp = 25
print(temp > 0 and temp < 100)   # True

# 4
total = 100
minutes = total // 60      # 1
seconds = total % 60       # 40
print(minutes, "分", seconds, "秒")

6. 输入输出

6.1 input:让用户输入内容

input() 会让程序停下来,等你在键盘上打字并按回车,然后把你输入的内容作为字符串返回(还给你)。

name = input("请输入你的名字:")
print("你好,", name)

运行后,程序会显示 请输入你的名字: 等你输入,你打 小明 回车,它就会打印 你好, 小明。

关键点:input() 拿到的永远是字符串(str)。如果你想拿它当数字用,必须自己转换:

age = input("请输入你的年龄:")     # 你输入 22,但 age 是字符串 "22"
age = int(age)                      # 转成整数
print("明年你就", age + 1, "岁了")

6.2 f-string:把变量"塞进"字符串里

很多时候你想打印一句带变量的完整句子,比如"氢的原子序数是 1"。如果硬用 + 拼,很麻烦(数字还得先转字符串)。f-string 让这件事变得超简单。

用法:在字符串开头加一个字母 f,然后在字符串里用花括号 {} 把变量名包起来:

element = "氢"
number = 1
print(f"{element}的原子序数是{number}")     # 氢的原子序数是1

mass = 1.008
print(f"{element}的相对原子质量约为{mass}")  # 氢的相对原子质量约为1.008

花括号里还可以直接放表达式(就是可以算的东西):

a = 3
b = 4
print(f"{a} 加 {b} 等于 {a + b}")     # 3 加 4 等于 7

还可以控制小数位数(科研里特别常用,比如保留两位小数):

pi = 3.1415926
print(f"π 约等于 {pi:.2f}")     # π 约等于 3.14,:.2f 表示保留2位小数

f-string 是 Python 3.6 之后的功能,Python 3.14 完全支持,放心用。

动手试试

  1. 写个程序,用 input 让用户输入一个元素符号,然后用 f-string 打印"你输入的元素是 XXX"。
  2. 让用户输入一个数字(字符串),转成整数,打印它的平方。
  3. 设 r = 2.5,用 f-string 打印 圆的半径是 2.50(保留两位小数)。

参考答案:

# 1
e = input("请输入一个元素符号:")
print(f"你输入的元素是 {e}")

# 2
n = input("请输入一个数字:")
n = int(n)
print(f"它的平方是 {n ** 2}")

# 3
r = 2.5
print(f"圆的半径是 {r:.2f}")

7. 控制流:if / elif / else

控制流 就是"让程序根据不同情况走不同的路"。比如"如果温度高于 100 度,就显示'沸腾',否则显示'未沸腾'"。

7.1 最简单的 if

temp = 120

if temp > 100:
    print("水沸腾了")

运行结果:水沸腾了。

结构拆解:

  • if 后面跟一个条件(一个能算出 True 或 False 的东西,比如 temp > 100),条件后面要加冒号 :。
  • 冒号下面的代码,要缩进(也就是在行首空几格)。缩进的这些代码,只有在条件为 True 时才会执行。

7.2 if / else:两种情况

temp = 60

if temp >= 100:
    print("沸腾")
else:
    print("没沸腾")

else 表示"否则",也就是条件不成立时执行的代码。else 后面也要冒号,它下面的代码同样要缩进。

7.3 if / elif / else:多种情况

elif 是 "else if"(否则如果)的缩写,用于"还有别的可能"的情况。比如给成绩分级:

score = 85

if score >= 90:
    print("优秀")
elif score >= 80:
    print("良好")
elif score >= 60:
    print("及格")
else:
    print("不及格")

程序从上往下依次检查,遇到第一个成立的条件就执行对应代码,然后跳过后面所有的。所以 85 会命中第二个 elif,打印"良好"。

7.4 缩进规则(新手最容易错的地方!)

Python 靠缩进来判断"哪些代码属于这个 if"。这是它和其他语言最大的不同,也是新手报错最多的原因。

规则:

  • 同一个 if 下面的代码,缩进必须一致(一般用 4 个空格,或按一次 Tab 键)。
  • 缩进必须严格对齐,多一个空格、少一个空格都可能报错。
x = 10
if x > 5:
    print("大于5")      # 缩进了,属于 if
    print("这行也属于 if")
print("这行不属于 if,无论如何都会执行")

运行结果:

大于5
这行也属于 if
这行不属于 if,无论如何都会执行

VS Code 里,你在冒号后回车,它会自动帮你缩进;按 Shift + Tab 可以减少缩进(退回一层)。

7.5 多个条件的组合

用 and、or 组合条件:

temp = 30
if 0 <= temp <= 100:          # 这种连续写法是 Python 特色,表示 temp 在 0 到 100 之间
    print("温度正常")

也可以写成 temp >= 0 and temp <= 100,两种都对。

再举个化学味儿的例子:判断元素状态(简单例举,别较真):

element = "Br"          # 溴
if element == "Br":
    print("常温下是液态非金属")
elif element in ["O", "H", "N","F","Cl"]:     # 这里用到了第10章才讲的列表和 in
    print("常温下是气体")
else:
    print("常温下通常是固体")

动手试试

  1. 写个程序,判断一个数 n 是正数、负数还是零。
  2. 写个程序,让用户输入一个元素符号,如果输入 "Au" 就打印"这是金",否则打印"这不是金"。
  3. 判断一个年份是不是闰年(能被 4 整除但不能被 100 整除,或者能被 400 整除)。

参考答案:

# 1
n = -5
if n > 0:
    print("正数")
elif n < 0:
    print("负数")
else:
    print("零")

# 2
e = input("请输入元素符号:")
if e == "Au":
    print("这是金")
else:
    print("这不是金")

# 3
year = 2024
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
    print("闰年")
else:
    print("不是闰年")

8. 循环:for 与 while

循环 就是"把一段代码重复执行很多次"。这是电脑最擅长的事——你写一遍,它替你跑一千遍。

8.1 for 循环:挨个遍历

for 循环的经典用法是:从一个"队伍"里,一个一个地把东西取出来,对每个东西做同样的事。

elements = ["H", "He", "Li", "Be", "B"]    # 一个元素符号的队伍(列表,第10章细讲)

for e in elements:        # 依次把 elements 里的每个元素拿出来,存进变量 e
    print(e)

运行结果:

H
He
Li
Be
B

读法:for e in elements 可以读作"对于 elements 里的每一个 e,做下面缩进里的事"。每取一个 e,就执行一遍缩进的代码。

对字符串也能遍历(字符串也是一个字符接一个字符):

for ch in "H2O":
    print(ch)
# 依次打印 H  2  O

8.2 range:生成一串整数

range(n) 生成"从 0 到 n-1"的整数。它常和 for 搭配,用来"重复 n 次":

for i in range(5):       # range(5) 是 0,1,2,3,4 这5个数
    print(i)
# 打印 0 1 2 3 4(注意没有 5!)

range 有三种用法:

range(5)          # 0 到 4
range(1, 6)       # 1 到 5(左闭右开:包含1,不包含6)
range(1, 10, 2)   # 1,3,5,7,9(第三个参数是"步长",每次加2)

记忆口诀:range 是"左闭右开",左边能取到,右边取不到。

for i in range(1, 6):
    print(f"第{i}次")     # 第1次 到 第5次

8.3 while 循环:条件满足就继续

while 是"只要条件还成立,就反复执行"。适合"不知道要循环几次,只知道什么时候该停"的情况。

n = 1
while n <= 5:
    print(n)
    n = n + 1          # 每次加1,不然会永远循环(死循环)
# 打印 1 2 3 4 5

一定要记得让条件最终变成 False(比如上面让 n 不断增加),否则程序会永远转下去,这叫死循环,只能按 Ctrl+C 强制停。

8.4 break 和 continue

  • break:立刻跳出整个循环,后面不管还有多少都不做了。
  • continue:跳过本次循环的剩余部分,直接进入下一轮。
for i in range(1, 11):
    if i == 5:
        break          # 到 5 就彻底停
    print(i)
# 打印 1 2 3 4
for i in range(1, 6):
    if i == 3:
        continue       # 跳过 3,但继续后面的
    print(i)
# 打印 1 2 4 5

8.5 循环里累加:科研里最常见的套路

求一组数据的总和、平均值,本质就是"循环 + 累加":

data = [25.1, 24.8, 25.3, 24.9, 25.0]     # 5次实验测得的温度

total = 0                    # 先建一个"存总和"的盒子,初始为 0
for x in data:
    total = total + x         # 每次把当前值加进去

print(f"总和 = {total}")
print(f"平均值 = {total / len(data)}")    # len(data) 是数据的个数

len(...) 是"数一数队伍里有几个"的意思,这里 len(data) 是 5。这个套路请一定亲手敲一遍,它是所有数据处理的基础。

动手试试

  1. 用 for + range 打印 1 到 100 里所有的偶数(提示:步长 2,从 2 开始)。
  2. 用 for 遍历 ["Na", "K", "Ca"],打印"元素 XX"。
  3. 用 while 从 10 倒数到 1。
  4. 求 1 到 100 所有整数的和(用累加套路)。

参考答案:

# 1
for i in range(2, 101, 2):
    print(i)

# 2
for e in ["Na", "K", "Ca"]:
    print(f"元素 {e}")

# 3
n = 10
while n >= 1:
    print(n)
    n = n - 1

# 4
total = 0
for i in range(1, 101):
    total = total + i
print(total)     # 5050

9. 字符串进阶

字符串(str)是科研文本处理的绝对主力——分子式、元素符号、文件名、日志,全是字符串。这一章把常用操作一次讲清。

9.1 索引:取出某个位置的字符

字符串里的每个字符都有编号,这个编号叫索引(index)。编号从 0 开始,不是从 1 开始!这是新手常忘的点。

字符串:  H   2   O
索引:   0   1   2
formula = "H2O"
print(formula[0])     # H
print(formula[1])     # 2
print(formula[2])     # O
print(formula[-1])    # O,-1 表示"倒数第一个"
print(formula[-3])    # H,-3 表示"倒数第三个"

负索引就是"从右边数",-1 是最后一个,-2 是倒数第二个。

9.2 切片:取出一段

切片(slice) 用 [开始:结束] 取出一段。规则和 range 一样:左闭右开,取得到开始,取不到结束。

s = "chemistry"
print(s[0:4])     # chem(索引0到3,不包含4)
print(s[4:7])     # ist
print(s[:4])      # chem(冒号前省略,表示从0开始)
print(s[4:])      # istry(冒号后省略,表示到最后)
print(s[-3:])     # try(最后3个)

还可以带步长:s[开始:结束:步长],比如 s[::2] 是"从头到尾每隔一个取一个"。

9.3 常用字符串方法

方法 就是"这个东西自带的、能用 . 点出来的功能"。字符串有很多方法,下面是最常用的:

方法作用例子结果
upper()全变大写"h2o".upper()"H2O"
lower()全变小写"H2O".lower()"h2o"
strip()去掉两头的空格/换行" H2O ".strip()"H2O"
split()按某个字符切开,返回列表"H,O,C".split(",")["H", "O", "C"]
replace(a,b)把 a 替换成 b"H2O".replace("2","")"HO"
join(列表)用本字符串把列表拼起来",".join(["H","O"])"H,O"
startswith(x)是否以 x 开头"data.csv".startswith("data")True
endswith(x)是否以 x 结尾"data.csv".endswith(".csv")True
formula = "  ch4  "
print(formula.strip())       # ch4(去掉空格)
print(formula.strip().upper())   # CH4

s = "Na,Cl,K"
parts = s.split(",")         # 用逗号切开
print(parts)                 # ['Na', 'Cl', 'K']

text = "mol/kg"
print(text.replace("mol/kg", "mol/L"))   # mol/L

split() 特别实用:从文本文件读一行 "25.1,24.8,25.3",split(",") 一下就拆成了三个数据。

9.4 in:判断一个字符串里有没有另一个字符串

print("H" in "H2O")       # True
print("Au" in "H2O")      # False
print("碳" in "二氧化碳")   # True

in 是"在...里面吗"的意思,结果 True/False,常配合 if 使用。

动手试试

  1. 字符串 s = "C6H12O6"(葡萄糖),用索引取出第 3 个字符(索引 2)。
  2. 用切片取出 s 的前两个字符。
  3. 把 "h2o" 变成全大写。
  4. 字符串 "C,H,N,O",用 split 拆成列表,再用 join 把它们用 - 连起来。

参考答案:

# 1
s = "C6H12O6"
print(s[2])              # H

# 2
print(s[:2])             # C6

# 3
print("h2o".upper())     # H2O

# 4
parts = "C,H,N,O".split(",")
print(parts)             # ['C', 'H', 'N', 'O']
print("-".join(parts))   # C-H-N-O

10. 列表 list

列表(list) 是"一个能装很多东西的有序盒子"。它用方括号 [] 包起来,里面的东西用逗号隔开。列表里的东西可以改、可以增删,非常灵活,是 Python 里最常用的数据结构。

10.1 创建列表

elements = ["H", "He", "Li", "Be"]     # 字符串列表
nums = [1, 2, 3, 4, 5]                 # 数字列表
mixed = ["H", 1, 1.008, True]          # 列表里可以混放不同类型(但不推荐乱混)
empty = []                             # 空列表
print(elements)

10.2 索引与切片(和字符串一模一样)

elements = ["H", "He", "Li", "Be"]
print(elements[0])        # H
print(elements[-1])       # Be
print(elements[1:3])      # ['He', 'Li']

10.3 改元素

列表和字符串的一个大区别:列表可以直接改(字符串不行,叫"不可变",第 11 章再细说)。

elements = ["H", "He", "Li"]
elements[0] = "氢"        # 把第0个改成"氢"
print(elements)           # ['氢', 'He', 'Li']

10.4 增删改查

操作说明例子
列表.append(x)在末尾加一个elements.append("B")
列表.insert(i, x)在指定位置 i 插入elements.insert(1, "Li")
列表.remove(x)删除第一个等于 x 的elements.remove("He")
列表.pop(i)删除位置 i 的元素并返回它x = elements.pop(0)
len(列表)列表里有几个元素len(elements)
x in 列表x 在不在列表里"H" in elements
elements = ["H", "He"]
elements.append("Li")        # ['H', 'He', 'Li']
elements.insert(1, "Be")     # ['H', 'Be', 'He', 'Li']
elements.remove("He")        # ['H', 'Be', 'Li']
last = elements.pop()        # 删掉最后一个 'Li',并把 'Li' 存进 last
print(last)                  # Li
print(elements)              # ['H', 'Be']
print(len(elements))         # 2

10.5 遍历列表

elements = ["C", "H", "O", "N"]
for e in elements:
    print(f"元素 {e}")

如果想同时拿到"序号"和"内容",用 enumerate:

for i, e in enumerate(elements):
    print(f"第{i}个是{e}")
# 第0个是C  第1个是H ...

10.6 排序:sort 和 sorted

  • 列表.sort():原地排序,直接改变原列表,不返回新列表。
  • sorted(列表):返回一个排好序的新列表,原列表不变。
nums = [3, 1, 4, 1, 5, 9, 2]

a = sorted(nums)       # 返回新列表,nums 不变
print(a)               # [1, 1, 2, 3, 4, 5, 9]
print(nums)            # [3, 1, 4, 1, 5, 9, 2](原样)

nums.sort()            # 原地排序,nums 自己被改了
print(nums)            # [1, 1, 2, 3, 4, 5, 9]

倒序加参数 reverse=True:

nums.sort(reverse=True)
print(nums)            # [9, 5, 4, 3, 2, 1, 1]

10.7 求最大最小值(不用自己写循环)

Python 内置了 max、min、sum:

data = [25.1, 24.8, 25.3, 24.9, 25.0]
print(max(data))     # 25.3
print(min(data))     # 24.8
print(sum(data))     # 125.1

有了这些,上一章"累加求平均"可以一行搞定:

print(sum(data) / len(data))    # 25.02

动手试试

  1. 建一个含 5 个元素符号的列表,打印第 2 个(索引 1)和最后一个。
  2. 往列表里 append 一个元素,再 insert 一个到开头(索引 0)。
  3. 对 [5, 2, 8, 1, 9] 用 sorted 排个序,再验证原列表没变。
  4. 求 [10, 20, 30, 40] 的和、最大值、元素个数。

参考答案:

# 1
el = ["H", "He", "Li", "Be", "B"]
print(el[1], el[-1])      # He B

# 2
el.append("C")
el.insert(0, "X")
print(el)

# 3
nums = [5, 2, 8, 1, 9]
print(sorted(nums))       # [1, 2, 5, 8, 9]
print(nums)               # [5, 2, 8, 1, 9]

# 4
a = [10, 20, 30, 40]
print(sum(a), max(a), len(a))   # 100 40 4

11. 元组、字典、集合

除了列表,Python 还有三种常用的"容器"。这一章讲清楚它们各自的用途和区别。

11.1 元组 tuple:不能改的列表

元组(tuple) 用圆括号 () 表示,它和列表几乎一样,但一旦创建就不能修改(不能增删改元素)。这叫"不可变"。

point = (3, 4)              # 一个坐标
colors = ("红", "绿", "蓝")
print(point[0])             # 3
print(len(colors))          # 3

为什么要有它?因为有些东西你不希望被不小心改掉,比如一个分子的固定参数、一个不可变的坐标。用元组可以"锁起来",让代码更安全。凡是你确定不会再改的固定数据,用元组更合适;需要随时增删改的,用列表。

# 下面这行会报错,因为元组不能改
# colors[0] = "黄"   # 会报 TypeError

11.2 字典 dict:给每个东西配一个"标签"

字典(dict) 用花括号 {},里面是**"键: 值"** 成对出现。键(key)相当于"标签",值(value)是标签对应的内容。它适合表示"一一对应"的关系。

最经典的例子:元素符号 → 原子序数。

atomic = {"H": 1, "He": 2, "Li": 3, "O": 8}
print(atomic["H"])      # 1,用键查值
print(atomic["O"])      # 8

结构拆解:{"H": 1} 里,"H" 是键,1 是值,中间用冒号,多对之间用逗号。

增删查改

atomic = {"H": 1, "O": 8}

# 查
print(atomic["H"])            # 1
print(atomic.get("Au"))       # None(用 get 查不存在的键不会报错,返回 None)
print(atomic.get("Au", "没找到"))  # 没找到(get 可以指定"找不到时返回啥")

# 增(直接给新键赋值)
atomic["C"] = 6

# 改(给已有键赋新值)
atomic["O"] = 8

# 删
del atomic["H"]               # 删掉 H 这一项
removed = atomic.pop("C")     # 删掉 C 并返回它的值 6

print(atomic)                 # {'O': 8}

判断键在不在

print("Au" in atomic)     # False

遍历字典

atomic = {"H": 1, "He": 2, "Li": 3}

for key in atomic:                    # 默认遍历的是"键"
    print(key)                        # H He Li

for key in atomic:
    print(f"{key} 的原子序数是 {atomic[key]}")

for key, value in atomic.items():     # items() 同时拿到键和值
    print(key, value)

11.3 集合 set:不重复、无顺序的一堆东西

集合(set) 也用花括号 {},但里面只有值,没有"键:值",而且元素不重复、没有固定顺序。它最大的用处是"去重"和"找交集/并集"。

s = {1, 2, 3, 3, 3}       # 重复的 3 会被自动去掉
print(s)                  # {1, 2, 3}

s.add(4)                  # 加一个
print(s)                  # {1, 2, 3, 4}

科研里典型用法:你有两组样品编号,想看它们共有的和全部不重复的:

group_a = {"A", "B", "C", "D"}
group_b = {"C", "D", "E", "F"}

print(group_a & group_b)   # 交集(两边都有):{'C', 'D'}
print(group_a | group_b)   # 并集(合起来,去重):{'A','B','C','D','E','F'}
print(group_a - group_b)   # 差集(A有B没有):{'A', 'B'}

去重:把一个列表直接塞进 set():

samples = ["A", "B", "A", "C", "B"]
unique = set(samples)      # {'A', 'B', 'C'}
print(unique)

11.4 三种容器对比

列表 list元组 tuple字典 dict集合 set
符号[ ]( ){键: 值}{ }
能否修改能不能能(值可改)能(增删元素)
有无顺序有有有(按插入序)无
是否可重复可可键不可重复不可重复
典型用途一堆同类数据固定不变的组合标签→内容 的对应去重、集合运算

动手试试

  1. 建一个元组存你的生日(年, 月, 日),打印月份(索引 1)。
  2. 建一个字典,存 3 个元素符号及其相对原子质量,查其中一个。
  3. 往上面的字典里加一个新元素,再删掉一个。
  4. 用集合对 [1,2,2,3,3,3,4] 去重。

参考答案:

# 1
birth = (2000, 5, 20)
print(birth[1])              # 5

# 2
mass = {"H": 1.008, "O": 15.999, "C": 12.011}
print(mass["O"])             # 15.999

# 3
mass["N"] = 14.007
del mass["C"]
print(mass)

# 4
print(set([1,2,2,3,3,3,4]))  # {1, 2, 3, 4}

12. 函数

函数(function) 是"一段起好名字、可以反复调用的代码块"。它是编程里最重要的思想之一,一定要弄懂。

12.1 为什么需要函数:把重复代码收起来

假设你要在程序里好多地方算"圆的面积"(面积 = π × r²)。每次都得写一遍公式,既啰嗦又容易错。函数就是把这个公式封装成一个小工具,起个名字,以后想用就"喊"它一声。

12.2 def:定义函数

def circle_area(r):                 # 定义一个函数,名字叫 circle_area,接收一个参数 r
    area = 3.14159 * r * r          # 函数体(缩进!)
    return area                     # 把结果"返回"给调用者

# 调用函数
a = circle_area(2)                  # r=2,算出面积存进 a
print(a)                            # 12.56636
print(circle_area(3))               # 28.27431

逐个拆解:

  • def:定义函数的关键词(define 的缩写)。
  • circle_area:函数名,你自己起的,规则和变量名一样。
  • (r):括号里是参数,就是"调用时传进来的数据"。这里 r 是半径。
  • return:把结果"交出去"。函数里 return 之后,函数就结束了。
  • 调用函数时写 circle_area(2),就是把 2 传给参数 r,然后执行函数体,把 return 的结果拿回来。

12.3 多个参数

def rectangle_area(width, height):
    return width * height

print(rectangle_area(3, 5))    # 15

12.4 参数默认值

给参数设一个默认值,调用时如果没传这个参数,就用默认值:

def greet(name, greeting="你好"):
    return f"{greeting},{name}"

print(greet("旅行者"))               # 你好,旅行者
print(greet("派蒙", "早上好"))      # 早上好,派蒙

注意:有默认值的参数必须放在没有默认值的参数后面。

12.5 没有 return 的函数

有些函数只是"做点事",不需要返回结果,这时可以不用 return(它实际上返回 None,表示"空"):

def show_element(element):
    print(f"这个元素是 {element}")

show_element("Fe")     # 打印:这个元素是 Fe

12.6 函数的好处(总结)

  • 避免重复:一处定义,处处使用。
  • 便于修改:公式改了,只改函数里一处。
  • 更清晰:给代码分块,一眼看懂结构。
  • 可复用:可以把函数存起来,以后别的项目接着用。

动手试试

  1. 定义一个函数 square(n),返回 n 的平方。
  2. 定义一个函数 mean(a, b, c),返回三个数的平均值。
  3. 定义一个函数 describe_element(symbol, number),打印"元素 XXX 的原子序数是 N",然后调用它试试。
  4. 定义一个函数,参数是"摄氏温度",返回"华氏温度"(公式:F = C × 9/5 + 32)。

参考答案:

# 1
def square(n):
    return n ** 2
print(square(7))              # 49

# 2
def mean(a, b, c):
    return (a + b + c) / 3
print(mean(1, 2, 3))          # 2.0

# 3
def describe_element(symbol, number):
    print(f"元素 {symbol} 的原子序数是 {number}")
describe_element("O", 8)      # 元素 O 的原子序数是 8

# 4
def c_to_f(c):
    return c * 9 / 5 + 32
print(c_to_f(100))            # 212.0

13. 模块与导入

13.1 模块是什么

模块(module) 就是"别人(或你自己)写好的、装了一堆现成函数和功能的文件"。你不需要什么都自己从头写,Python 自带了很多"标准库"模块,直接用就行。

导入 就是"把这个模块拿进来用"。

13.2 import:导入模块

import math          # 导入数学模块

print(math.pi)       # 3.141592653589793
print(math.sqrt(16)) # 4.0,开平方
print(math.floor(3.7))  # 3,向下取整
print(math.ceil(3.2))   # 4,向上取整

注意用法:导入了 math 后,要用 math.xxx 这种"模块名点功能"的方式调用。

random 模块(生成随机数)也很有用:

import random

print(random.random())          # 生成 [0,1) 之间的随机小数
print(random.randint(1, 6))     # 生成 1 到 6 之间的随机整数(含1和6),像掷骰子
print(random.choice(["H", "O", "C", "N"]))   # 从列表里随机选一个
print(random.uniform(0, 10))    # 生成 0 到 10 之间的随机小数

13.3 from ... import ...:只导入某个功能

这样以后可以直接用名字,不用加"模块名."前缀:

from math import sqrt, pi

print(sqrt(25))     # 5.0
print(pi)           # 3.14159...

13.4 自己写模块

其实你写的 .py 文件本身就是一个模块。比如你写了个 mytools.py,里面定义了几个函数,另一个文件就能导入它:

# 假设有个 mytools.py 文件,内容如下:
def double(x):
    return x * 2
# 在同一个文件夹的另一个文件里:
import mytools
print(mytools.double(5))    # 10

13.5 pip:安装第三方库

标准库之外,还有海量的第三方库(别人写好上传到网上的),用 pip 来安装。pip 是 Python 自带的"安装器"。

在终端里(先 conda activate py314):

pip install numpy

意思就是"用 pip 装 numpy 这个库"。装完后就能 import numpy 用了。

常用命令:

pip install 包名          # 安装
pip uninstall 包名        # 卸载
pip list                  # 看装了什么

国内安装如果很慢,可以加清华镜像源加速:

pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

动手试试

  1. 用 math 模块算 2 的平方根和 3 的 2 次方(math.pow)。
  2. 用 random 生成 5 个 1 到 100 之间的随机整数(提示:用 for 循环)。
  3. 用 from math import factorial,算 5 的阶乘(factorial(5))。

参考答案:

# 1
import math
print(math.sqrt(2))      # 1.414...
print(math.pow(3, 2))    # 9.0

# 2
import random
for i in range(5):
    print(random.randint(1, 100))

# 3
from math import factorial
print(factorial(5))      # 120

14. 文件读写

科研里,数据几乎都存在文件里。学会读写文件,你才能让程序真正"处理数据"。

14.1 打开、读、关闭

读一个文本文件,最经典的写法:

f = open("data.txt", "r", encoding="utf-8")   # 打开文件,"r" 表示读(read)
content = f.read()                             # 把整个文件内容读成一个字符串
print(content)
f.close()                                      # 用完要关掉
  • open(文件名, 模式, encoding=...):打开文件。
    • 模式 "r" 表示读,"w" 表示写(会覆盖原内容),"a" 表示追加(往末尾加)。
  • encoding="utf-8":一定要写,尤其是 Windows 下中文文件,不写可能乱码或报错。
  • 用完 close() 关闭文件,释放资源。

14.2 with 语句:自动关闭(推荐)

手动 close() 容易忘(尤其中间报错时)。用 with 可以自动帮你关闭,这是标准推荐写法:

with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)
# 出了 with 的缩进块,文件会自动关闭,不用写 close()

14.3 逐行读取

数据文件常常是"一行一个数据",用 readlines() 读成"每行是一个元素的列表",或直接 for 循环逐行读:

# 方法1:readlines()
with open("data.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()      # 每一行(含末尾换行符)作为列表的一个元素
    for line in lines:
        print(line.strip())    # strip 去掉行尾的换行符和空格

# 方法2:直接 for 循环文件对象(推荐,更省内存)
with open("data.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())

14.4 写文件

with open("output.txt", "w", encoding="utf-8") as f:
    f.write("第一行内容\n")      # \n 是"换行符"
    f.write("第二行内容\n")

注意:模式 "w" 会覆盖原文件(如果文件已存在,内容被清空重写)。想保留旧内容往末尾加,用 "a"(append)。

14.5 完整例子:读一行一个数值,转成数字算总和

假设 data.txt 内容是一行一个温度值:

25.1
24.8
25.3
24.9
25.0
values = []                          # 建空列表存数字
with open("data.txt", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()          # 去掉换行符
        if line:                     # 跳过空行
            values.append(float(line))   # 转成浮点数,存进列表

print(values)                        # [25.1, 24.8, 25.3, 24.9, 25.0]
print(f"平均值 = {sum(values) / len(values)}")

这是科研数据处理的最基础骨架,请务必亲手跑一遍。第 17 章的综合项目就是它的升级版。

动手试试

  1. 写一个程序,创建一个文件 hello.txt,写入两行文字。
  2. 再读回这个文件,把内容打印出来。
  3. 写一个程序,把 [1.5, 2.5, 3.5] 三个数,每个一行写入 nums.txt,然后再读出来求平均值。

参考答案:

# 1
with open("hello.txt", "w", encoding="utf-8") as f:
    f.write("你好\n")
    f.write("Python\n")

# 2
with open("hello.txt", "r", encoding="utf-8") as f:
    print(f.read())

# 3
with open("nums.txt", "w", encoding="utf-8") as f:
    for n in [1.5, 2.5, 3.5]:
        f.write(str(n) + "\n")          # 数字要先转字符串才能写

with open("nums.txt", "r", encoding="utf-8") as f:
    nums = []
    for line in f:
        nums.append(float(line.strip()))
print(sum(nums) / len(nums))            # 2.5

15. 错误与异常

写代码一定会遇到报错,这不代表你笨,而是编程的日常。关键是学会看懂报错、知道怎么改。

15.1 几种最常见的报错

NameError:用了没定义的名字

print(mass)      # 如果从没定义过 mass,会报 NameError: name 'mass' is not defined

原因:变量没定义就用了,或者拼写错了(比如定义了 mass,却写成了 mss)。

TypeError:类型不对

print("数字" + 5)     # TypeError: can only concatenate str (not "int") to str

原因:字符串和数字不能直接 +。要么把 5 转成字符串,要么别用 + 拼。

IndexError:索引越界

el = ["H", "He"]
print(el[5])      # IndexError: list index out of range(列表只有2个元素,索引0和1)

原因:访问的位置超出了范围。记住索引从 0 开始,最大是 长度-1。

ValueError:值不对

int("abc")        # ValueError: invalid literal for int()

原因:"abc" 没法转成数字。

SyntaxError:语法错误(最常见,比如少冒号、少括号)

if True
    print("x")   # SyntaxError:if 后面少了冒号

原因:标点符号写错了。仔细看报错提示指向的那一行。

FileNotFoundError:文件找不到

open("不存在的文件.txt")    # FileNotFoundError

原因:文件名写错,或程序运行的目录里没有这个文件。

15.2 怎么看懂报错信息

报错信息通常会告诉你三件事,看例子:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(mass)
NameError: name 'mass' is not defined
  • File "test.py", line 3:错误出在哪个文件的第 3 行——这是定位问题的关键。
  • NameError:错误类型。
  • name 'mass' is not defined:具体原因描述。

技巧:从报错信息的最后一行往上读,最后一行往往是问题的本质,前面告诉你发生在哪一行。

15.3 try / except:让程序别一报错就崩溃

有些错误是可以预见的(比如用户可能输入了没法转数字的内容)。用 try/except 可以"试着做,做不成就走备用方案":

raw = input("请输入一个数字:")
try:
    num = float(raw)          # 试着转成浮点数
    print(f"它的平方是 {num ** 2}")
except ValueError:            # 如果转失败(输入的不是数字),就走这里
    print("你输入的不是数字!")

结构:

  • try: 下面放"可能出错"的代码。
  • except 错误类型: 下面放"出错时怎么办"。
  • 程序不会因为 try 里的错误而崩溃,而是跳到 except 继续跑。

try/except 还能处理文件不存在的情况:

try:
    with open("data.txt", "r", encoding="utf-8") as f:
        print(f.read())
except FileNotFoundError:
    print("没找到 data.txt 这个文件")

动手试试

  1. 故意写一个 NameError,运行看报错,然后改正它。
  2. 写一个程序,让用户输入一个整数,如果输入的不是整数(比如 abc),用 try/except 打印"请输入整数"。
  3. 访问列表 [1,2,3] 的索引 10,看看报什么错,再用 try/except 把它接住。

参考答案:

# 2
raw = input("请输入一个整数:")
try:
    n = int(raw)
    print(f"你输入的是 {n}")
except ValueError:
    print("请输入整数")

# 3
try:
    print([1,2,3][10])
except IndexError:
    print("索引越界了")

16. 面向对象入门(可选)

这一章是可选的,第一次读不懂可以先跳过,不影响你完成前面的所有内容。但了解个大概,对以后看别人的代码很有帮助。

16.1 类(class)和对象(object)是什么,用大白话讲

想象你要在程序里描述"分子"这个东西。每个分子都有一些属性(名字、分子式、相对分子质量)和一些行为(比如"显示自己的信息")。

  • 类(class) 就是"图纸 / 模板"——它规定了"分子应该有什么属性、什么行为"。
  • 对象(object) 就是"照着图纸造出来的具体实例"——一个具体的分子,比如 H2O。

类定义"长什么样",对象是"具体的那一个"。

16.2 定义一个类

class Molecule:                        # 定义一个叫 Molecule 的类
    def __init__(self, name, formula):  # 特殊方法:造对象时自动运行,设置初始属性
        self.name = name                # 把传入的 name 存到对象自己的 name 属性上
        self.formula = formula

    def show(self):                     # 普通方法:显示信息
        print(f"分子 {self.name} 的化学式是 {self.formula}")

# 造两个对象(叫"实例化")
m1 = Molecule("水", "H2O")
m2 = Molecule("甲烷", "CH4")

m1.show()          # 分子 水 的化学式是 H2O
m2.show()          # 分子 甲烷 的化学式是 CH4

逐个拆解(先有个印象就行):

  • class Molecule: 定义类。
  • __init__ 是"构造方法",在创建对象时自动调用,用来给对象设置初始属性。self 表示"对象自己"。
  • self.name = name:把参数 name 存成对象自己的属性 name。
  • def show(self):对象的方法,用 对象名.show() 调用。

16.3 为什么用面向对象

当你有很多"同类型、各有属性、要做同样操作"的东西时,用类可以把"数据"和"操作数据的方法"打包在一起,代码更清晰、更不容易乱。对于科研新手,先用函数就够了,等遇到真正需要时再深入。

到这里,你已经覆盖了 Python 最核心的语法。下一章我们把前面学的串起来,做一个真正有用的脚本。


17. 综合小项目:处理一组实验数据

17.1 项目目标

写一个完整脚本,完成下面这件事:

  1. 读入一个数据文件(一行一个数值,比如一批实验测得的温度/能量值)。
  2. 算出数据个数、总和、平均值、最大值、最小值。
  3. 把结果写进一个新的结果文件 result.txt。

这个脚本你以后能直接改一改用来处理自己的真实数据。

17.2 先准备数据文件

先手动建一个 data.txt(用 VS Code 或记事本),内容是一行一个数值:

25.1
24.8
25.3
24.9
25.0
26.2

17.3 完整代码

# 文件名:analyze_data.py
# 功能:读入一组实验数据,计算统计量,写入结果文件

INPUT_FILE = "data.txt"       # 输入文件名(大写表示这是"常量",约定俗成)
OUTPUT_FILE = "result.txt"    # 输出文件名

def read_data(filename):
    """从文件读取数据,每行一个数值,返回浮点数列表。"""
    values = []
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()          # 去掉换行符和空格
            if line:                     # 跳过空行
                values.append(float(line))   # 转成浮点数存起来
    return values

def analyze(values):
    """计算一组数据的统计量,返回结果字典。"""
    n = len(values)                       # 数据个数
    total = sum(values)                   # 总和
    mean = total / n                      # 平均值
    return {
        "个数": n,
        "总和": total,
        "平均值": mean,
        "最大值": max(values),
        "最小值": min(values),
    }

def write_result(stats, filename):
    """把统计结果写入文件。"""
    with open(filename, "w", encoding="utf-8") as f:
        f.write("===== 数据分析结果 =====\n")
        for key, value in stats.items():      # 遍历字典的键和值
            f.write(f"{key}: {value:.3f}\n")  # 保留3位小数

# ---- 主程序:按顺序调用上面的函数 ----
data = read_data(INPUT_FILE)          # 1. 读数据
print(f"共读入 {len(data)} 个数据:{data}")

stats = analyze(data)                 # 2. 算统计量
print("统计结果:", stats)

write_result(stats, OUTPUT_FILE)      # 3. 写结果
print(f"结果已写入 {OUTPUT_FILE}")

17.4 运行与检查

在 VS Code 里运行(或终端里 python analyze_data.py),屏幕会显示:

共读入 6 个数据:[25.1, 24.8, 25.3, 24.9, 25.0, 26.2]
统计结果: {'个数': 6, '总和': 151.3, '平均值': 25.216..., '最大值': 26.2, '最小值': 24.8}
结果已写入 result.txt

打开 result.txt,你会看到:

===== 数据分析结果 =====
个数: 6.000
总和: 151.300
平均值: 25.217
最大值: 26.200
最小值: 24.800

17.5 拆解:这个脚本用了哪些前面学的知识

  • 函数(第 12 章):把"读数据、算统计、写结果"分成三个函数,各管一件事。
  • 文件读写 + with(第 14 章):读 data.txt、写 result.txt。
  • 列表 + 循环 + 累加(第 8、10 章):把每行转成数字存进列表。
  • 字符串 strip / float 转换(第 4、9 章):清理换行、类型转换。
  • 字典 + items() 遍历(第 11 章):存统计结果并遍历输出。
  • f-string(第 6 章):格式化输出。

17.6 自己动手改一改(挑战)

  1. 让程序同时算标准差(公式:先求每个数与平均值的差的平方的平均,再开平方)。提示:用 math.sqrt,用循环或列表推导。
  2. 改成读入"逗号分隔"的数据(一行 25.1,24.8,25.3),用 split(",") 拆开。
  3. 加一个 try/except,如果文件不存在就友好提示。

参考答案(标准差 + 逗号分隔 + 容错):

import math

def read_data_comma(filename):
    values = []
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line:
                for piece in line.split(","):      # 按逗号拆
                    piece = piece.strip()
                    if piece:
                        values.append(float(piece))
    return values

def std(values):
    mean = sum(values) / len(values)
    variance = sum((x - mean) ** 2 for x in values) / len(values)  # 方差
    return math.sqrt(variance)                                      # 标准差

# 主程序
try:
    data = read_data_comma("data.txt")
    print(f"平均值 = {sum(data)/len(data):.3f}")
    print(f"标准差 = {std(data):.3f}")
except FileNotFoundError:
    print("找不到数据文件")

18. 新手常见坑清单

这一章把新手最容易栽跟头的地方集中列出来,强烈建议打印贴在显示器旁边。

坑 1:缩进不一致

if True:
    print("A")
   print("B")      # 错!缩进比上面少了一个空格,会报 IndentationError

规则:同一层代码缩进必须完全一致(建议统一用 4 个空格)。VS Code 里按 Tab 会自动缩进 4 格。

坑 2:中文/全角符号

这是中国新手第一大坑!编程必须用**英文(半角)**的标点符号,尤其是:

错误(全角)正确(半角)
( ) 中文括号( )
“” ‘’ 中文引号" '
, 中文逗号,
: 中文冒号:
print(“hello”)     # 错!全是中文标点,报 SyntaxError
print("hello")       # 对

技巧:写代码时把输入法切到英文状态。引号、括号、逗号、冒号都要是英文的。注释里的中文没关系,但代码本身的标点必须是英文。

坑 3:= 和 == 混淆

  • = 是赋值:把右边的值放进左边变量。
  • == 是比较:判断左右是否相等,结果是 True/False。
x = 5           # 赋值,x 现在是 5
if x == 5:      # 比较,判断 x 是否等于 5
    print("x 是 5")

if x = 5: 会直接报错,因为 = 不是判断。

坑 4:变量没定义 / 拼写错误

mass = 1.008
print(mas)      # NameError,少写了个 s

仔细看报错里提示的变量名,对照你定义的名字。

坑 5:索引从 0 开始

el = ["H", "He", "Li"]
print(el[3])    # IndexError!只有 0、1、2 三个索引

第一个元素索引是 0,最后一个是 len(el) - 1(这里是 2)。想取最后一个,直接用 el[-1]。

坑 6:input() 返回的是字符串

n = input("请输入数字:")   # 你输入 10,n 是字符串 "10"
print(n + 1)               # TypeError!字符串不能和数字相加

要先 n = int(n) 转成数字。

坑 7:编码问题(Windows 特有)

Windows 下读中文文件如果不指定编码,可能乱码或报错。读写文件都加 encoding="utf-8":

with open("data.txt", "r", encoding="utf-8") as f:
    ...

坑 8:修改字符串时以为能直接改

字符串是"不可变"的,不能 s[0] = "x"。要改就用切片拼或 replace:

s = "H2O"
# s[0] = "X"     # 错!字符串不能这样改
s = "X" + s[1:]  # 对,重新拼一个

坑 9:忘了冒号 :

if、for、while、def、class 这些行的末尾都要加冒号:

for i in range(3):     # 冒号不能少
    print(i)

坑 10:整数除法取整想当然

Python 3 里 / 永远是小数结果(浮点),要整除用 //:

print(10 / 4)    # 2.5
print(10 // 4)   # 2

19. 下一步学什么 + 推荐资源

19.1 恭喜你

到这里,你已经掌握了 Python 最核心的语法:变量、类型、运算、输入输出、判断、循环、字符串、列表/字典/集合、函数、模块、文件读写、异常处理。这些是所有 Python 程序的地基,后面学的任何高级内容都建立在这上面。

19.2 下一步学什么(按对你科研的优先级)

  1. 数据科学三件套(强烈建议优先):

    • NumPy:高效处理数值数组,是科学计算的基础。
    • pandas:处理表格数据(像 Excel 但强得多)。
    • Matplotlib:画图(折线、散点、直方图)。
    • 这三者的教程在你本教程的同目录下都有:NumPy教程.md、pandas教程.md、Matplotlib教程.md。
  2. 科研工具:等你需要做具体科研时再学:

    • ASE(原子模拟环境)、pymatgen(材料学)、RDKit(化学信息学)、SciPy、scikit-learn(机器学习)——这些教程也在同目录下。
  3. 进阶语言特性(有基础后再回来):

    • 列表推导式、lambda、生成器、装饰器、类型注解。

19.3 推荐资源

  • 官方文档:https://docs.python.org/zh-cn/3/(有中文版,权威但稍硬核,遇到问题查)。
  • 菜鸟教程:https://www.runoob.com/python3/(中文,适合查阅)。
  • 廖雪峰 Python 教程:https://www.liaoxuefeng.com/wiki/1016959663602400(经典中文教程)。
  • 《Python编程:从入门到实践》(书):全球最畅销的入门书之一,有大量动手项目。
  • B站:搜"Python 零基础",找播放量高的系统课程跟着做。

19.4 最后的话

学编程没有捷径,唯一的秘诀是:多写、多错、多改。今天学的每一个小知识点,都亲手敲一遍、改一改、故意弄错一次看看报错长什么样。坚持一个月,你会发现:以前那些要手动点半天的数据处理,现在写几行代码就搞定了。

祝你学习顺利,科研路上 Python 能成为你可靠的助手!


本教程完。如果你按顺序走完了 19 章,并亲手敲过每个例子,你就已经是一名"会写 Python"的人了。接下来去学 NumPy、pandas、Matplotlib,把它们用到你的真实数据上吧。