🍓 第六章 开发 Python 程序
📄 一句话概括

前面两节都是"场地准备";本节开始真正写代码。 变量是"给数据起名字",运算符是"拿数据做运算"——这两样加起来,就是所有程序的 90% 内容。本节还会专门盯住 Python 和 C++ 最不一样的四五个点(它们正是老手翻车的地方)。

📝 本节和前面几节的关系

6-1 讲过 Python 不用声明类型、没有分号;本节第一次实际用上这两条——你会发现"不写 int"是真省事,但也会踩到它带来的新问题(类型是悄悄变的,得靠 type() 去问)。 本节所有内容都在交互模式(>>>)里练——短、快、立刻看到结果,这是学语言最快的方式(6-2 讲的第一种方式)。 读法建议:每个例子都亲手敲一遍。变量和运算符不靠理解,靠手感。

一、变量:给数据起个名字

变量的作用只有一句话:把数据存起来,起个名字,以后用名字叫它。

>>> age = 18
>>> age
18
>>> age + 2
20

读法:age = 18 不是数学上的"等于",而是 "把 18 装进名叫 age 的盒子"。

💡 为什么编程里这个符号该读成"装进"而不是"等于"

因为 x = x + 1 在 Python 里是完全合法的——数学上它无解,但在这里它的意思是: "把 x 盒子里的数拿出来、加 1、再装回 x 盒子"。 这在程序里太常见了(计数器加一),所以一定把 = 读成【装进】。

1.1 与 C++ / Java 的第一个大差别:不用声明类型

age = 18
price = 9.9
name = "树莓派"
ok = True

就这么四行,一个类型都没写,Python 自己看值决定:

名字 值 Python 自己判定的类型
age 18 整数 int
price 9.9 小数 float
name "树莓派" 字符串 str
ok True 布尔 bool

对照 C++(回顾 变量):

int age = 18;
double price = 9.9;
std::string name = "树莓派";   // 还得 #include <string>
bool ok = true;                // 注意 C++ 是小写 true
📝 这叫「动态类型」

变量的类型跟着值走,不跟着名字走。所以同一名字可以先后装不同类型:

x = 5          # 现在是整数
x = "五"       # 变成字符串了,没人拦你

好处:写起来快、不用纠结类型。代价:写错了也不会当场报错——所以你会需要 type() 这个工具(见第三节)。

1.2 命名规则:三条硬规矩 + 一条软约定

硬规矩(违反就是语法错误):

规矩 例子
只能由字母、数字、下划线组成 user_age ✅/user-age ❌(连字符被当成减号)
不能以数字开头 age1 ✅/1age ❌
不能是 Python 的关键字 if、for、class、True 这些都不行

软约定(不遵守也能跑,但会被嫌弃):

⚠️ 别用中文当变量名

Python 3 技术上允许中文变量名(秒数 = 10 能跑),但一律别这么写。两个理由: ① 社区代码全是英文——你要抄、要改、要在网上提问,看不懂英文名寸步难行; ② 混排时容易踩隐形的坑(中文标点和英文标点看起来像、实际是两个字符;; 和 ; 就经常认错)。 本节下面的例子全用英文名——现在多认几个词,后面硬件章节会轻松很多。

📝 大小写敏感——这个会被坑很多次

age、Age、AGE 是三个完全不同的变量。 Python 里所有名字都区分大小写,包括 True / False / None 这几个特殊值也必须是首字母大写。写成 true 会报 NameError(在 C++ / Java 里 true 是小写,习惯得改)。

二、数据类型:五大金刚

Python 内置类型很多,入门只需认这五个:

类型 写起来 是什么 例子
int 18 整数(不限大小!) 0、-5、1000000000000
float 9.9 小数(浮点数) 3.14、-0.5、1.0
str "你好" 字符串(一段文字) "abc"、"你好"、"123"
bool True / False 真 / 假(只有两个值) True、False
None None 空,什么都没有 None
⚠️ 三个新手必踩的点

① "123" 和 123 是两回事。 前者是字符串(一段文字),后者是整数。加了引号就不再是数字了——它不能做加减。

② int 不限大小。 C++ 里 int 有上限(约 21 亿,超了会溢出变成负数);Python 的整数想多大就多大,算 2 ** 1000 也没问题。这是给新手的福利。

③ None 是"没有值",不是 0、不是空字符串。 它表示"这里暂时什么都没有"——比如一个还没赋值的配置项。它的首字母必须大写。

2.1 提前打预防针:小数的精度问题

>>> 0.1 + 0.2
0.30000000000000004

不是 Python 的 bug,是所有编程语言的通病(C++ / Java 也一样)。原因是计算机用二进制存小数,0.1 这种十进制小数存不精确。

💡 记住一句话就够

涉及小数比较,永远不要用 ==。

>>> 0.1 + 0.2 == 0.3
False          # 你以为是 True

要比较就"看差得够不够小":abs(a - b) < 0.000001。这一条以后做传感器数据处理时会天天用到。

三、运算符:算数、比较、逻辑

3.1 算术运算符(七个,注意其中两个和 C++ 不同)

运算符 意思 例子 结果
+ 加 7 + 3 10
- 减 7 - 3 4
* 乘 7 * 3 21
/ 除(重点) 10 / 2 5.0 ← 是小数!
// 整除(取商的整数部分) 10 // 3 3
% 取余 10 % 3 1
** 幂(乘方) 2 ** 10 1024
⚠️ `10 / 2` 等于 `5.0` 不是 `5`——这是从 C++ / Java 过来的人第一个翻车点

在 C++ / Java 里,两个整数相除,结果还是整数(10 / 3 得 3,小数部分直接扔掉)。 Python 里 / 永远返回小数——哪怕能整除也给你 5.0。

想要整数结果就用 //:

>>> 10 / 3      # 真除法
3.3333333333333335
>>> 10 // 3     # 整除(只要整数部分,不四舍五入)
3
>>> 10 % 3      # 取余(剩下多少)
1

验证一下:3 * 3 + 1 = 10 ✅(整除的结果 × 除数 + 余数 = 原数,这是取余的定义)

// 和 % 是天生一对——分东西的时候必用:

>>> total = 3661                 # 一共多少秒
>>> hours = total // 3600        # 里面有 1 个整小时
>>> rest = total % 3600          # 去掉整小时后,还剩 61 秒
>>> minutes = rest // 60         # 61 秒里有 1 个整分钟
>>> seconds = rest % 60          # 最后剩 1 秒
>>> print(hours, minutes, seconds)
1 1 1

验证:1 小时 = 3600 秒,加 1 分钟 60 秒,加 1 秒 = 3661 ✅ 对得上。

📝 `**` 是 Python 的礼物

C++ 里算乘方要调函数 pow(2, 10),Python 直接给你一个运算符 2 ** 10。 这在树莓派上很实用——算第几位 GPIO、算内存大小(2 ** 20 就是 1MB)都用它。

3.2 字符串运算符(只有两个能用)

运算 例子 结果
拼接 + "树莓" + "派" '树莓派'
重复 * "口" * 3 '口口口'
不能用 -、/ "abc" - "a" ❌ 报错
⚠️ `"3" + 4` 会直接报错——这在 Java / C++ 里是合法的!
>>> "3" + 4
TypeError: can only concatenate str (not "int") to str

Java 会默默把 4 转成文字拼起来(得到 "34");C++ 也差不多。 Python 不惯着你——它认为"文字加数字"没有明确定义,宁可报错也不猜。 解法就是显式转换:"3" + str(4) 得到 '34',或者 int("3") + 4 得到 7。你要哪个?Python 让你自己说清楚。

字符串另一个特别常用的是 f-string(下一小节专门讲)。

3.3 比较运算符(结果是 True / False)

运算符 意思 例子 结果
== 相等 3 == 3 True
!= 不等 3 != 4 True
> < >= <= 大小 5 >= 5 True
⚠️ `=` 和 `==` 是两个完全不同的东西

= 是赋值(装进盒子),== 是比较(问是否相等)。

x = 5      # 把 5 装进 x
x == 5     # 问:x 是不是 5? → True

这是新手最常见的笔误之一。好消息是 Python 会拦你(写成 if x = 5: 直接语法错误),不像 C++ 里 if (x = 5) 是合法的、会悄悄改掉 x 的值。

3.4 逻辑运算符:and / or / not

Python 用英文单词,不用符号(C++ / Java 用的是 && / || / !):

Python C++ / Java 意思
and && 两个都真才真
or \|\| 有一个真就真
not ! 反过来
>>> temp = 25
>>> temp > 20 and temp < 30
True
>>> not (temp > 30)
True
📝 为什么 Python 用单词

呼应 6-1 说的"Python 之禅"——可读性优先。and 比 && 更像人话,尤其对非程序员。 但小心:& 和 | 在 Python 里是另一组运算符(按位运算),用在条件判断里结果完全不对。布尔判断一律用 and / or。

3.5 增强赋值:+= 这类简写

x = x + 1 写多了很啰嗦,所以有简写:

简写 等于
x += 1 x = x + 1
x -= 1 x = x - 1
x *= 2 x = x * 2
x /= 2 x = x / 2
>>> stock = 10
>>> stock += 5
>>> stock
15
⚠️ Python 里没有 `++` 和 `--`!
>>> x = 5
>>> x++
  File "<stdin>", line 1
    x++
       ^
SyntaxError: invalid syntax

C++ / Java 里 x++ 是"加一",Python 里根本没这个语法。 想加一就写 x += 1。这是从 C 系语言过来的人最常写错的一行。

四、type()、input() 与类型转换(本节最关键的一段)

4.1 type():问一个值"你是什么"

因为动态类型不会报错,所以你需要主动去问:

>>> type(18)
<class 'int'>
>>> type(9.9)
<class 'float'>
>>> type("18")
<class 'str'>
>>> type(True)
<class 'bool'>

注意 type("18") 的结果是 str——加了引号就是文字,哪怕内容全是数字。这是本课后面最容易出错的地方。

4.2 input():从键盘要一个值——它永远给你字符串!

>>> name = input("请输入你的名字:")
请输入你的名字:波仔
>>> print("你好," + name + "!")
你好,波仔!

看起来很顺。但换成数字就翻车了:

>>> age = input("你多大了?")
你多大了?18
>>> age + 1
TypeError: can only concatenate str (not "int") to str

为什么? 因为 input() 拿到的永远是字符串——你敲的是 18,它给你的是 "18"(带引号的文字)。文字不能加数字。

⚠️ 这是 Python 新手第一大坑,一定记死

input() 的返回值一定是 str。 想要数字,必须自己转:

>>> age = int(input("你多大了?"))
你多大了?18
>>> age + 1
19

而且这个坑还有个变体:如果你敲的不是数字(比如敲了"十八"),int() 会直接崩:

ValueError: invalid literal for int() with base 10: '十八'

这个"用户输入不可信"的问题,后面讲异常处理时会正式解决。

4.3 类型转换四兄弟

函数 作用 例子 结果
int(x) 转整数 int("18") / int(3.9) 18 / 3(直接截断,不四舍五入)
float(x) 转小数 float("3.14") / float(5) 3.14 / 5.0
str(x) 转字符串 str(18) '18'
bool(x) 转布尔 bool(0) / bool("") / bool(7) False / False / True
💡 `bool()` 的规律(以后极常用)

"空"和"零"是 False,其他都是 True: - 0、0.0 → False - ""(空字符串)、[](空列表)→ False - None → False - 其他一切(非零数、非空字符串)→ True

所以判断"用户有没有输入内容",写 if 输入: 就够,不用写 if 输入 != "":。

4.4 f-string:把变量塞进句子里(现代 Python 最常用的写法)

最老的拼接方式:

name = "波仔"
print("你好," + name + ",今天天气不错。")

f-string(Python 3.6 起,现在一律用它):

name = "波仔"
temp = 25.6
print(f"你好,{name},现在室温 {temp} 度。")

输出:你好,波仔,现在室温 25.6 度。

三个要点:

  1. 字符串前面加一个 f(format 的意思)——不加就变成普通文字,{} 里原样输出。
  2. {} 里可以直接写变量名,也可以写表达式:f"两数之和是 {3 + 4}"。
  3. 它还能顺手做格式化(这个很实用): ```python

    pi = 3.14159265 f"{pi:.2f}" # 保留两位小数 '3.14' count = 7 f"{count:03d}" # 补零到三位 '007' ```

💡 为什么推荐 f-string

对比三种写法:"你好," + name / "你好,{}".format(name) / f"你好,{name}"。 第三种最短、最像人话、最不容易错(前两种你必须数括号和加号对不对得上)。 呼应 6-2 的坑:拼接时 + 两边必须都是字符串,f-string 则自动帮你转——f"年龄{18}" 是合法的,"年龄" + 18 会报错。

五、动手 Demo:写一个"秒数换算器"

把本节学到的东西串起来。在命令行里写(无头模式的做法见 6-2):

mkdir -p ~/projects
cd ~/projects
nano sec2hms.py

内容:

# 秒数换算器:把一大堆秒,换算成几小时几分几秒
total = int(input("请输入秒数:"))

hours = total // 3600        # 一个小时 3600 秒,整除得到小时数
rest = total % 3600          # 去掉整小时后,还剩多少秒
minutes = rest // 60         # 剩下的秒里有多少个整分钟
seconds = rest % 60          # 最后剩几秒

print(f"{total} 秒 = {hours} 小时 {minutes} 分 {seconds} 秒")

# 顺便算点别的
print(f"这相当于 {total / 60:.1f} 分钟")
print(f"一天有 86400 秒,这些秒占一天的 {total / 86400 * 100:.2f}%")

跑:

python3 sec2hms.py

输入 3661,看到什么算成功:

请输入秒数:3661
3661 秒 = 1 小时 1 分 1 秒
这相当于 61.0 分钟
一天有 86400 秒,这些秒占一天的 4.24%

读结果(每一步都验算给你看):

算式 计算过程 结果 对不对
3661 // 3600 3661 里有 1 个整 3600 1 小时 ✅
3661 % 3600 3661 − 3600 余 61 秒 ✅
61 // 60 61 里有 1 个整 60 1 分钟 ✅
61 % 60 61 − 60 余 1 秒 ✅
验算 1×3600 + 1×60 + 1 = 3661 ✅ 回到原数
3661 / 60 真除法 61.0166…,格式化成 61.0 ✅
3661 / 86400 * 100 3661÷86400×100 4.2372…%,格式化成 4.24% ✅

再试一个:输入 86399,应该得到 23 小时 59 分 59 秒、1439.98 分钟、100.00%(真实值是 99.9988…%——这正好演示了"格式化会四舍五入",它把 99.9988 显示成了 100.00)。

六、30 秒实验

实验一:亲眼看见 / 和 // 的区别

>>> 7 / 2
3.5
>>> 7 // 2
3
>>> 7 % 2
1
>>> type(7 / 2)
<class 'float'>
>>> type(7 // 2)
<class 'int'>

7 / 2 连类型都变了(float)—— 这是 Python 和 C++ 最硬的一个差别。

实验二:亲眼看见"文字不是数字"

>>> type("18")
<class 'str'>
>>> "18" * 3
'181818'
>>> 18 * 3
54

看见了吗:"18" * 3 不是乘法,是字符串重复三次(得到 '181818')。引号一加,它就从"数"变成了"一串字符"——这是个非常容易看走眼的坑。

实验三:小数精度

>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 + 0.2 == 0.3
False
>>> round(0.1 + 0.2, 2)
0.3

round(值, 位数) 是"四舍五入到几位小数"——显示数字时可以用它,但比较大小还是别用 ==。

实验四:bool() 的规律

>>> bool(0), bool(1)
(False, True)
>>> bool(""), bool("0")
(False, True)

注意 bool("0") 是 True(因为 "0" 是非空字符串,是"有东西",不是"零")——这一条骗过无数人。

七、常见误区

  1. "10 / 2 应该等于 5" —— 在 Python 里它等于 5.0(浮点数)。/ 永远返回小数,要整数用 //。这是 C++ / Java 转过来最常见的错。
  2. "x++ 是加一" —— Python 没有 ++ / --,会直接 SyntaxError。写 x += 1。
  3. "input() 拿到的是数字" —— 永远是字符串。做算术前必须 int() 或 float() 转一遍(int(input(...)) 是最常见的写法)。
  4. ""3" + 4 会自动拼成 "34"" —— 那是 Java / C++ 的行为。Python 直接报 TypeError,逼你说清楚到底是要"拼字"还是"算数"。要拼就 str(4),要算就 int("3")。
  5. "true / false / none 小写也行" —— 不行。这三个特殊值必须首字母大写:True / False / None。小写会报 NameError(true 在 C++ / Java 里是小写,习惯得改)。
  6. "小数比较用 == 没问题" —— 有问题。0.1 + 0.2 == 0.3 的结果是 False。小数比较要用"差值够小"的方式。
  7. "变量名随便起,反正能跑" —— 能跑,但过两天你自己看不懂。用有意义的名字,并且跟着 Python 社区用下划线(led_pin 而不是 ledPin)。
自测三问(点开对答案) 1. `10 / 2` 和 `10 // 2` 的结果分别是什么?类型分别是什么? 2. `input()` 拿到的值是什么类型?要拿它做算术该怎么办? 3. 为什么写 `f"{temp:.1f}"` 比写 `"温度是" + str(temp)` 更好? **参考答案** 1. **`10 / 2` 得 `5.0`(`float`);`10 // 2` 得 `5`(`int`)**。Python 的 `/` 是"真除法",**永远返回小数**——哪怕除得尽;要整数结果用 `//`。(这一点和 C++ / Java 的 `int / int = int` 完全不同。) 2. **永远是 `str`(字符串)**,哪怕你敲的是一串数字。要算术就得自己转:**`int(input("提示语"))`** 或 `float(...)`。 3. **因为它自动帮你把数字转成文字,而且能顺手格式化**(`.1f` 表示保留一位小数)。用 `+` 拼接时两边的类型必须都是字符串,**写成 `"温度是" + temp` 会直接报 `TypeError`**,还必须手动 `str()` 一层,又长又容易漏括号。

相关笔记