前面两节都是"场地准备";本节开始真正写代码。 变量是"给数据起名字",运算符是"拿数据做运算"——这两样加起来,就是所有程序的 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 这些都不行 |
软约定(不遵守也能跑,但会被嫌弃):
- 全小写 + 下划线分隔,叫蛇形命名:
user_name、max_speed、led_pin(C++ / Java 习惯是驼峰userName——Python 社区一律用下划线,跟着来) - 名字要有意义:
a、b、x1这种,过两天你自己都看不懂 - 全大写表示"常量"(Python 没有真正的常量,这是君子协定):
MAX_SPEED = 100
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 |
在 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 ✅ 对得上。
C++ 里算乘方要调函数 pow(2, 10),Python 直接给你一个运算符 2 ** 10。
这在树莓派上很实用——算第几位 GPIO、算内存大小(2 ** 20 就是 1MB)都用它。
3.2 字符串运算符(只有两个能用)
| 运算 | 例子 | 结果 |
|---|---|---|
拼接 + |
"树莓" + "派" |
'树莓派' |
重复 * |
"口" * 3 |
'口口口' |
不能用 -、/ |
"abc" - "a" |
❌ 报错 |
>>> "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
呼应 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
>>> 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"(带引号的文字)。文字不能加数字。
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 |
"空"和"零"是 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 度。
三个要点:
- 字符串前面加一个
f(format 的意思)——不加就变成普通文字,{}里原样输出。 {}里可以直接写变量名,也可以写表达式:f"两数之和是 {3 + 4}"。- 它还能顺手做格式化(这个很实用):
```python
pi = 3.14159265 f"{pi:.2f}" # 保留两位小数 '3.14' count = 7 f"{count:03d}" # 补零到三位 '007' ```
对比三种写法:"你好," + 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" 是非空字符串,是"有东西",不是"零")——这一条骗过无数人。
七、常见误区
- "
10 / 2应该等于 5" —— 在 Python 里它等于5.0(浮点数)。/永远返回小数,要整数用//。这是 C++ / Java 转过来最常见的错。 - "
x++是加一" —— Python 没有++/--,会直接SyntaxError。写x += 1。 - "
input()拿到的是数字" —— 永远是字符串。做算术前必须int()或float()转一遍(int(input(...))是最常见的写法)。 - "
"3" + 4会自动拼成"34"" —— 那是 Java / C++ 的行为。Python 直接报TypeError,逼你说清楚到底是要"拼字"还是"算数"。要拼就str(4),要算就int("3")。 - "
true/false/none小写也行" —— 不行。这三个特殊值必须首字母大写:True/False/None。小写会报NameError(true在 C++ / Java 里是小写,习惯得改)。 - "小数比较用
==没问题" —— 有问题。0.1 + 0.2 == 0.3的结果是False。小数比较要用"差值够小"的方式。 - "变量名随便起,反正能跑" —— 能跑,但过两天你自己看不懂。用有意义的名字,并且跟着 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()` 一层,又长又容易漏括号。- ☐ 下一节(6-4 Python 流程控制)
相关笔记
- 在树莓派开发 Python 程序 —— 上一节:这些例子都在那里学的交互模式里练
- 变量 —— 「必须声明类型」的对照;变量到底是什么,那里讲得更细
- 数据类型 —— 类型系统对照(C++ 有 int 上限,Python 整数不限大小)
- 运算符 —— 运算符分类的对照;
/与//的差别在那里是本课没提过的 - ☕ Java 基础 · 索引 —— Java 的字符串拼接行为,正好和 Python 相反
- 🍓 树莓派 · 索引 —— 全课路线图