Python 是什么
Python 是一门由 Guido van Rossum(吉多·范罗苏姆)于 1991 年发布的高级通用编程语言。它以可读性强、语法简洁、生态庞大著称,被广泛应用于 Web 开发、数据分析、人工智能、自动化运维等领域。本节将带你理解 Python 的语言定位、执行模型与设计哲学,建立对这门语言的完整认知。
前置知识
阅读本节前,建议先了解:Python 教程首页,对本站的学习路线与阶段划分有一个整体印象。
基础概念
Python 是一门高级(High-level)、通用(General-purpose)、解释型(Interpreted)、动态类型(Dynamically typed)的编程语言。它不强制你在编写代码前声明变量类型,也不需要手动管理内存,而是由解释器与垃圾回收器(Garbage Collector)在运行时处理。Python 强调「可读性优先」,用缩进(Indentation)表达代码块层级,而非花括号。
Python 同时支持面向对象(OOP)、面向过程与函数式(Functional)三种编程范式,你可以按需选择,而不必被单一范式约束。它既是脚本语言,也可用于构建大型工程系统。
| 术语 | 英文 | 含义 |
|---|---|---|
| 解释型语言 | Interpreted Language | 源码由解释器逐条翻译执行,无需预先整体编译为机器码 |
| 动态类型 | Dynamically Typed | 变量类型在运行时确定,无需声明 |
| 强类型 | Strongly Typed | 不同类型间不会隐式做危险转换(如 "1" + 1 会报错) |
| 高级语言 | High-level Language | 屏蔽内存与硬件细节,贴近自然语言表达 |
| 通用语言 | General-purpose Language | 不局限于某一领域,可开发各类程序 |
「动态类型」与「强类型」这两个标签常被混淆,二者的组合关系可参考下表:
| 语言 | 类型检查时机 | 类型转换策略 | 组合标签 |
|---|---|---|---|
| Python | 运行时(动态) | 拒绝隐式转换(强) | 动态强类型 |
| JavaScript | 运行时(动态) | 允许隐式转换(弱) | 动态弱类型 |
| Java | 编译期(静态) | 拒绝隐式转换(强) | 静态强类型 |
| C | 编译期(静态) | 允许部分隐式转换(弱) | 静态弱类型 |
语法与用法
Python 程序的入口极其简单,一行 print() 即可输出内容:
# 最简可运行的 Python 程序
print("Hello, World!")Hello, World!这段代码体现了 Python 的核心特征:没有 main 函数样板,没有分号结尾,没有类型声明,语句本身就是构成程序的基本单位。
再看一个稍微完整一点的例子,感受变量、函数与 f-string 的写法:
# 变量无需声明类型,赋值即创建
name: str = "小码农"
projects: int = 12
# 定义函数时使用类型提示(Type Hints)
def intro(user: str, count: int) -> str:
"""生成一句自我介绍"""
return f"我是 {user},已完成 {count} 个项目。"
print(intro(name, projects))我是 小码农,已完成 12 个项目。命名由来
「Python」并非指蟒蛇,而是来自英国喜剧团体 Monty Python。Guido van Rossum 是该剧团的粉丝,因此给语言起了这个「短小、略带神秘感」的名字。
详细说明
Python 的执行模型
Python 代码不会直接编译成 CPU 能执行的机器码(Machine Code),而是经历「源码 → 字节码(Bytecode) → 虚拟机执行」的过程:
# 演示:查看 Python 编译产生的字节码指令
import dis
source = "result = 1 + 2"
# compile() 把源码编译为代码对象(Code Object)
code = compile(source, "<demo>", "exec")
# dis 模块反汇编代码对象,展示字节码
dis.dis(code) 0 0 RESUME 0
1 2 LOAD_CONST 0 (3)
4 STORE_NAME 0 (result)
6 RETURN_CONST 0 (None)字节码是介于源码与机器码之间的一种中间指令,它由 Python 虚拟机(PVM, Python Virtual Machine)逐条解释执行。因此 Python 常被称作「解释型语言」,但更准确的说法是「先编译为字节码、再由虚拟机解释执行」。
从源码到执行结果,完整的生命周期如下:
| 阶段 | 产物 | 说明 |
|---|---|---|
| 词法分析 | Token 流 | 把源码拆分为关键字、标识符、字面量 |
| 语法分析 | AST | 构建抽象语法树,描述代码结构 |
| 编译 | 字节码 / .pyc | 生成可执行的字节码对象并缓存 |
| 执行 | 运行时结果 | PVM 逐条执行字节码 |
首次导入模块时,CPython 会把字节码缓存为 __pycache__/xxx.cpython-312.pyc,下次运行直接复用,从而跳过编译阶段。
# 查看当前目录下的字节码缓存
ls -l __pycache__/-rw-r--r-- 1 user staff 284 Oct 8 10:00 demo.cpython-312.pycPython 的多种实现
「Python」既是语言规范,也是多个实现(Implementation)的统称。最常见的实现是 CPython:
| 实现 | 底层语言 | 特点 | 适用场景 |
|---|---|---|---|
| CPython | C | 官方参考实现,生态最完整 | 绝大多数场景 |
| PyPy | RPython | 带 JIT,纯计算场景更快 | 长时间运行的计算密集任务 |
| Jython | Java | 运行在 JVM 上 | 需与 Java 生态集成 |
| IronPython | C# | 运行在 .NET 上 | 需与 .NET 集成 |
| MicroPython | C | 极简,可跑在单片机上 | 嵌入式与物联网 |
因此当人们说「Python 慢」时,通常指的是 CPython 实现相对较慢,PyPy 等实现可以显著改善特定场景的性能。判断当前使用的是哪个实现,可以查看 sys.implementation:
import sys
import platform
print(sys.implementation.name) # cpython
print(sys.implementation.version) # 版本元组,如 (3, 12, 5, 'final', 0)
print(platform.python_version()) # 3.12.5
print(sys.version) # 含编译信息的完整版本字符串cpython
(3, 12, 5, 'final', 0)
3.12.5
3.12.5 (main, Aug 6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.3.9.4)]Python 的设计哲学
Python 有一套明确的设计信条,称为「Python 之禅」(The Zen of Python),可用 import this 打印:
import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Readability counts.
...核心思想可以概括为:优雅优于丑陋,明确优于隐晦,简单优于复杂,可读性很重要。这些信条直接影响了 Python 的语法设计,例如强制缩进、拒绝多重含义的表达式、限制隐式类型转换等。下表给出了信条与具体语法设计的对应关系:
| 设计信条 | 对应的语言设计 |
|---|---|
| Explicit is better than implicit | 拒绝隐式类型转换,导入必须显式写出 |
| Simple is better than complex | 只有一种明显的写法(One obvious way) |
| Readability counts | 强制缩进,禁止压缩为一行 |
| Errors should never pass silently | 异常必须显式捕获,避免静默失败 |
| There should be one obvious way | 用标准库统一方案,减少方言 |
Python 的类型系统:动态且强类型
Python 变量在赋值时才与对象绑定,且类型在运行时确定,但不同类型之间不会「偷偷」转换:
# 动态类型:同一个变量可以先后绑定不同类型的对象
value = 42 # 此时 value 绑定 int
value = "forty-two" # 现在绑定 str,合法
print(value)
# 强类型:不同类型不会隐式转换
try:
print("1" + 1) # 错误!字符串与整数不能相加
except TypeError as exc:
print(f"TypeError: {exc}")forty-two
TypeError: can only concatenate str (not "int") to str这意味着 Python 比 JavaScript 更「严格」:JS 中 "1" + 1 得到 "11",而 Python 会直接抛出 TypeError,从而避免隐蔽的 Bug。
从 Python 3.5 起引入、3.9+ 逐步完善、3.12 大幅增强的类型提示(Type Hints),让 Python 在保持动态类型的同时获得静态检查能力:
# Python 3.12+:类型参数语法(PEP 695)
type Vector = list[float] # 类型别名
def scale(v: Vector, factor: float) -> Vector:
"""按比例缩放向量"""
return [x * factor for x in v]
print(scale([1.0, 2.0, 3.0], 2.5))[2.5, 5.0, 7.5]类型提示不会影响运行时行为,但配合 mypy、pyright 等工具可在编码阶段发现类型错误,是大型项目的必备实践。
Python 的运行方式
Python 有三种常见的运行方式,理解它们有助于后续学习:
# 方式一:交互式解释器(REPL, Read-Eval-Print Loop)
python3
# 方式二:直接运行脚本文件
python3 hello.py
# 方式三:以模块方式运行(常用于包内脚本)
python3 -m http.server 8000# hello.py 文件内容
print("以脚本方式运行")推荐初学者先用交互式 REPL 快速验证语法,再逐步过渡到脚本文件开发。三种方式的对比如下:
| 运行方式 | 典型命令 | 适用场景 |
|---|---|---|
| 交互式 REPL | python3 | 试验语法、查看文档、调试片段 |
| 脚本文件 | python3 app.py | 编写可复用的程序 |
| 模块运行 | python3 -m json.tool | 运行包内模块、使用标准库工具 |
| 单行命令 | python3 -c "print(1+1)" | Shell 脚本中嵌入短逻辑 |
实战示例
示例一:统计一段文本的词频
下面这个例子综合体现了 Python 的简洁与强大:字典、字符串方法、排序一次性串联完成。
# 统计文本中出现次数最多的单词
from collections import Counter
text = """
Python is powerful and fast.
Python plays well with others.
Python runs everywhere.
Python is friendly and easy to learn.
Python is open.
"""
# 统一转小写并按空白切分,得到单词列表
words = text.lower().split()
# Counter 是标准库提供的计数器,专门用于统计频次
counter = Counter(words)
# most_common(3) 返回出现次数最多的前三个
for word, count in counter.most_common(3):
print(f"{word:>10} 出现 {count} 次") python 出现 5 次
is 出现 4 次
and 出现 3 次示例二:批量处理文件名
Python 在自动化场景中尤其高效。以下示例演示如何用几行代码批量给文件加前缀:
from pathlib import Path
# 使用当前目录下的 demo 文件夹作为演示
folder = Path("./demo")
folder.mkdir(exist_ok=True)
# 创建几个演示文件
for name in ("a.txt", "b.txt", "c.txt"):
(folder / name).touch()
# 为所有 .txt 文件添加前缀 backup_
for path in folder.glob("*.txt"):
new_name = folder / f"backup_{path.name}"
path.rename(new_name)
print(f"已重命名:{path.name} -> {new_name.name}")已重命名:a.txt -> backup_a.txt
已重命名:b.txt -> backup_b.txt
已重命名:c.txt -> backup_c.txt示例三:用 Python 解决一个实际问题
初学者常问「Python 到底能做什么」。下面这个例子读取一组销售记录,计算总额并输出格式化报表,代码不到 20 行,却覆盖了字典、循环、f-string 与排序:
# 一组简化的销售记录:商品名 -> (单价, 数量)
sales: dict[str, tuple[float, int]] = {
"键盘": (199.0, 12),
"鼠标": (89.0, 30),
"显示器": (1299.0, 5),
"主机": (4599.0, 3),
}
total = 0.0
rows: list[tuple[str, float, int, float]] = []
for product, (price, qty) in sales.items():
amount = price * qty
total += amount
rows.append((product, price, qty, amount))
# 按销售额从高到低排序
rows.sort(key=lambda row: row[3], reverse=True)
print(f"{'商品':<8}{'单价':>10}{'数量':>8}{'金额':>14}")
print("-" * 40)
for product, price, qty, amount in rows:
print(f"{product:<8}{price:>10.2f}{qty:>8}{amount:>14.2f}")
print("-" * 40)
print(f"{'合计':<8}{'':>10}{'':>8}{total:>14.2f}")商品 单价 数量 金额
----------------------------------------
主机 4599.00 3 13797.00
显示器 1299.00 5 6495.00
鼠标 89.00 30 2670.00
键盘 199.00 12 2388.00
----------------------------------------
合计 25350.00示例四:查询当前解释器能力
入门阶段养成「先探测环境」的习惯,可以避免大量兼容性问题:
import sys
# 校验最低版本,低于要求直接退出
MIN_VERSION = (3, 12)
if sys.version_info < MIN_VERSION:
raise SystemExit(
f"需要 Python {'.'.join(map(str, MIN_VERSION))} 或更高版本,"
f"当前为 {'.'.join(map(str, sys.version_info[:3]))}"
)
# 查看解释器支持的优化开关与实现信息
print(f"解释器实现:{sys.implementation.name}")
print(f"版本号:{'.'.join(map(str, sys.version_info[:3]))}")
print(f"默认编码:{sys.getdefaultencoding()}")
print(f"文件系统编码:{sys.getfilesystemencoding()}")解释器实现:cpython
版本号:3.12.5
默认编码:utf-8
文件系统编码:utf-8注意事项
- Python 2 与 Python 3 不兼容:
print在 Python 2 中是语句,在 Python 3 中是函数。本站全部内容基于 Python 3.12+,请勿使用 Python 2 运行示例。 - 缩进即语法:Python 用缩进表示代码块,同一代码块缩进必须一致。混用 Tab 与空格会触发
TabError。 - 强类型不等于声明类型:Python 是动态类型语言,但不会像 JavaScript 那样做隐式转换,
"1" + 1会报错而非得到"11"。 - 交互式与脚本模式差异:REPL 中会自动打印表达式结果,脚本文件中必须显式使用
print()。 - 不要用 Python 的内置名做变量名:如
list、dict、str、id等,覆盖后会引发难以排查的问题。 python与python3可能指向不同版本:在 macOS/Linux 上python可能不存在或指向旧版本,建议统一使用python3或通过版本管理工具固定。.pyc缓存不等于源码保护:字节码可被反编译,不要把「编译」当作加密手段。
最佳实践
- 统一使用 Python 3.12 及以上版本:享受类型参数、更好的错误提示与性能优化。
- 优先使用标准库:Python 的标准库被称为「自带电池(Batteries Included)」,遇到需求先查标准库,避免重复造轮子。
- 代码即文档:由于 Python 强调可读性,命名清晰、结构简单的代码本身就是最好的注释。
- 用虚拟环境(Virtual Environment)隔离依赖:不同项目依赖互不污染,从入门阶段就养成习惯。
- 善用
help()与dir():在 REPL 中随时查看对象的文档与属性,比死记硬背更高效。 - 给公共函数加类型提示:即使不启用静态检查器,类型提示也能显著提升可读性。
- 脚本入口使用
if __name__ == "__main__"::让模块既能被导入复用,又能被独立执行。
# 推荐:可导入也可独立运行的脚本骨架
def main() -> None:
"""脚本主逻辑"""
print("程序开始运行")
if __name__ == "__main__":
# 仅当直接执行本文件时才运行,被 import 时不执行
main()下一节
继续学习:Python 的特点与优势