Python 是这本书用来做实验的语言:动态类型、一切皆对象、不写就不占——它和 C 正好是两种极端,对照着看最能理解【语言给了你什么、又替你做掉了什么】。
附录 1 看的是 C(贴近硬件、类型严),这个附录看 Python(离人近、约束少)——两边对照,正好把语言这层看明白。
一、Python的特点
解释型:写完直接运行,不用编译(第七章讲过解释器和字节码这条路)。 动态类型:不声明类型,变量想装什么就装什么——代价是有些错要到运行时才现形。 可读性优先:靠缩进划分代码块,所以它常常被拿来当教学语言。 慢但不碍事:纯 Python 比 C 慢不少,可它把大量繁重活儿交给了用 C 写的底层——比如本书的 Demo 能跑得快,靠的就是这个。
二、一切皆对象
这句话是 Python 的底层信条:整数、字符串、列表、函数、模块、类型本身,全都是对象。 所以它们都有类型:连函数都是 builtin_function_or_method,模块就是 module。 带来的直接好处:函数可以当参数传出去、当返回值送回来——这就是各种【回调】写法的地基。 和 C 对照着看最清楚:C 里函数和数据泾渭分明,Python 里两者都可以装进变量。
三、数据类型
数值:int(能一直长)、float、bool。 文本:str——注意它数的是【字符个数】,不是字节数。 容器:list(可变)、tuple(不可变)、dict(键值)、set(不重复)。 和 C 最大的不同:Python 的整数不会溢出,容器会自动扩容——代价是这些都要额外开销。
四、输入、运算、输出
输出就是 print:不用格式符,什么类型都能直接打出来。 输入就是 input:拿回来的一定是字符串,要数字得自己转换。 运算符比 C 多一些:有整除、有乘方、有字符串重复。 还有一处很贴心的地方:整数除法默认给浮点结果,不会像 C 那样悄悄丢小数。
五、创建和使用函数
用 def 定义,不用写返回类型:def add(a, b): return a + b。
参数可以带默认值:def f(a, b=1),调用的时候可以少写一个。
函数里改参数:改不可变对象不会影响外面;改列表这类可变对象就会。
这一条最容易踩坑——它和 C 的【参数是复制进去的】看起来矛盾,其实是【复制的是引用】。
六、局部变量与全局变量
函数里赋值的名字默认是局部变量——要改全局的,得显式声明 global。 局部变量随函数结束而消失,和 C 一样住在栈上(第十章讲过栈帧)。 但 Python 的局部变量不用先声明类型,甚至连【有没有这个变量】都是运行时才确定的。 这也解释了一件事:为什么 C 里能靠编译器抓出的错,Python 里往往要跑起来才暴露。
七、数组与循环
Python 的【数组】是列表(list):能装不同类型、能随时加长。
循环用 for 和 while:for x in [1, 2, 3] 直接遍历元素,不用管下标。
要下标就用 enumerate,要同时遍历两个列表就用 zip。
底层对照:这些循环落到 CPU 上,还是第十章看到的那套【比较、执行、跳回去】。
八、其他语法
缩进就是语法:没有花括号,缩进错了程序就错——这让代码整齐,也让格式问题变成语法问题。 import 引入模块:和 C 的 #include 目的相似,但时机不同——Python 是运行时真正去执行那个模块。 有异常处理(try):C 里通常靠返回值判断,Python 里更常用抛异常。 最后一句:语言给的东西不一样,但底下那台机器是一样的——这正是这本书从头到尾想让人看到的。
九、动手 Demo:亲手尝试Python
【📋 实操路径】Python 连编译都不用:python hello.py 就跑了。 实测它的三个特点:动态类型、一切皆对象、长度算法和 C 不同。
items = [("a = 1", 1), ('a = "字"', "字"), ("a = [1, 2]", [1, 2])]
for code, val in items:
print(code, "->", type(val).__name__)
for name, obj in (("函数 len", len), ("模块 sys", sys), ("类型 int", int)):
print(name, "->", type(obj).__name__)
print(len("汉字abc"), "个字符", len("汉字abc".encode()), "个字节")
实跑输出:
--------------------------------------------------------------------
亲手尝试Python
--------------------------------------------------------------------
【📋 实操路径】**Python 的第一次运行更省事:连编译都不用。**
写文件 hello.py
运行 python hello.py
(也可以敲 python 进交互模式,一行一行试)
**一、不用声明类型,变量想装什么就装什么:**
写法 a 是什么
--------------------------------------------
a = 1 int
a = "字" str
a = [1, 2] list
a = {1: 2} dict
同一个名字 a,先后装过 4 种类型,全程没人拦着
**C 里这行代码根本通不过编译**——**类型一旦定下来就不能反悔。**
**这就是【动态类型】和【静态类型】的分界:省事的代价是【有些错要到运行时才发现】。**
**二、一切皆对象——连函数和类型本身都是:**
值 它的类型
--------------------------------------------
整数 1 int
字符串 "x" str
列表 [1] list
函数 len builtin_function_or_method
模块 sys module
类型 int type
**在 Python 里没有【不是对象】的东西**——**函数可以当参数传、类型可以拿来造对象。**
这一点和 C 差别很大:**C 里函数是函数、数据是数据,泾渭分明。**
**三、长度算法也不一样:**
len("汉字abc") 5
UTF-8 编码后 9 字节
**Python 数的是【字符个数】,C 数的是【字节个数】。**
**这就是同一个字符串两种语言会给出不同答案的原因**——**也是跨语言传数据要指定编码的原因。**
实测:同一个名字 a 先后装过 int、str、list 都没人拦着;连函数、模块、类型本身都是对象。 len 数的是 5 个字符,UTF-8 编码后是 9 个字节——所以跨语言传数据必须说清编码。
30 秒实验
- 把一段 C 风格的写法改写成 Python,感受一下省掉了哪些东西。
- 想一想:为什么 Python 慢一些,却仍然被大量用来做数据分析和 AI。
常见误区
- 以为不用声明类型就没有类型。类型一直在,只是不用你写出来。
- 以为 len 数的是字节。它数的是字符,字节数要用编码后去量。
自测三问(点开对答案)
1. Python 的【一切皆对象】是什么意思? —— 整数、字符串、列表、函数、模块、类型全都是对象,都有类型,所以函数也能当参数传。 2. 动态类型省了什么、又带来了什么代价? —— 省掉了类型声明;代价是有些类型错误要到运行时才暴露。 3. 为什么 len("汉字abc") 是 5 而 UTF-8 要 9 字节? —— len 数的是字符个数,C 风格的字节数要按编码去量,一个汉字在 UTF-8 里占 3 字节。- ☑ 全书已完结:12 章正文 + 5 个专栏 + 2 个附录,共 93 篇。
相关笔记
- 亲手尝试C语言 — 另一种极端的语言
- Python交互模式的使用方法 — 也是在这门语言上动手
- 在任何地方都能提供相同运行环境的Java虚拟机 — 解释执行那条路线
- ⌨️ 编程原理 · 索引 — 把编程全貌理一遍
- ⚙️ 程序是怎样跑起来的 · 索引