Python:从玩具到世界第一语言的30年

有些语言的诞生是为了解决问题。
有些语言的诞生是因为"为什么不呢?"
Python 属于后者。
1991 年,一个荷兰程序员在圣诞节无聊,决定写一门新语言。他叫 Guido van Rossum。他当时大概没想到,这个决定会改变整个软件行业。
先说结论
Python 成功不是因为它是"最好的"语言。
它成功是因为它让普通人也能写代码。
易读、易学、生态丰富——这三个特点,让它成为数据科学、AI、自动化领域的默认选择。
历史:一个意外
1989 年,ABC 的遗产
Guido 在 CWI(荷兰数学与计算机科学中心)工作,参与一门叫 ABC 的语言开发。
ABC 的目标很理想:让非程序员也能编程。
但 ABC 失败了。原因很多:名字奇怪、不能访问文件系统、性能差。
Guido 学到了教训:
- 名字要好记(Python 来自他喜欢的喜剧团体 Monty Python)
1991 年,Python 0.9.0
第一个公开发行版。功能简单:
看起来不像革命。但它有个杀手级特点:可读性。
# 1991 年的 Python 代码defgreet(name): print("Hello, " + name)greet("World")
和今天的 Python 几乎一样。
2000 年,Python 2.0
社区驱动的转折点。
Python 开始从"小众脚本语言"变成"通用编程语言"。
2008 年,Python 3.0
痛苦但必要的重生。
Guido 决定不向后兼容,修复历史遗留问题:
这个决定分裂了社区十年。直到 2020 年 Python 2 停止维护,战争才结束。
回头看,这是正确的决定。 没有这个决定,Python 无法适应现代需求。
2020 年代,AI 时代的王
机器学习爆发,Python 成为最大受益者。
TensorFlow、PyTorch、scikit-learn、NumPy、Pandas——整个 AI 生态建立在 Python 之上。
这不是偶然。是 30 年"易用性优先"哲学的自然结果。
Python 能做什么?
1. 数据科学与机器学习
这是 Python 今天的王牌领域。
import pandas as pdfrom sklearn.linear_model import LinearRegression# 读取数据data = pd.read_csv("sales.csv")# 训练模型model = LinearRegression()model.fit(data[["ad_spend"]], data["revenue"])# 预测prediction = model.predict([[10000]])print(f"投入 1 万广告,预计收入: {prediction[0]:.2f}")
三行代码,一个预测模型。
谁在用:Netflix、Spotify、NASA、每一家对冲基金。
2. Web 开发
Django、Flask、FastAPI 三足鼎立。
# FastAPI 示例from fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI()classUser(BaseModel): name: str email: str@app.post("/users")asyncdefcreate_user(user: User):return {"message": f"创建用户: {user.name}"}# 运行: uvicorn main:app --reload
谁在用:Instagram、Pinterest、Uber 的部分服务。
3. 自动化与脚本
Python 最原始的用途,今天依然强大。
import osimport shutilfrom datetime import datetime# 整理下载文件夹downloads = "/Users/you/Downloads"for file in os.listdir(downloads):if file.endswith(".pdf"): shutil.move(f"{downloads}/{file}",f"{downloads}/PDFs/{file}" )elif file.endswith((".jpg", ".png")): shutil.move(f"{downloads}/{file}",f"{downloads}/Images/{file}" )print(f"整理完成: {datetime.now()}")
谁在用:系统管理员、测试工程师、所有想偷懒的人。
4. DevOps 与云基础设施
import boto3# AWS SDK 示例ec2 = boto3.client("ec2")# 启动实例response = ec2.run_instances( ImageId="ami-12345678", InstanceType="t2.micro", MinCount=1, MaxCount=1,)instance_id = response["Instances"][0]["InstanceId"]print(f"启动实例: {instance_id}")
Ansible、SaltStack、AWS CLI 都是用 Python 写的。
5. 游戏开发(小规模)
import pygamepygame.init()screen = pygame.display.set_mode((800, 600))running = Truewhile running:for event in pygame.event.get():if event.type == pygame.QUIT: running = False screen.fill((0, 0, 0)) pygame.draw.circle(screen, (255, 0, 0), (400, 300), 50) pygame.display.flip()pygame.quit()
不是 3A 大作,但独立游戏、原型开发够用。
6. 科学计算
import numpy as npimport matplotlib.pyplot as plt# 生成数据x = np.linspace(0, 10, 100)y = np.sin(x)# 绘图plt.plot(x, y)plt.title("正弦波")plt.savefig("sine_wave.png")
科学家的最爱。比 MATLAB 便宜,比 C 容易。
实现原理:解释器如何工作
编译 vs 解释
Python 是解释型语言,但不完全是。
实际流程是这样的:
源代码 (.py) ↓词法分析 → 语法分析 → 抽象语法树 (AST) ↓编译成字节码 (.pyc) ↓Python 虚拟机执行字节码
字节码是什么?
字节码是 Python 的中间表示。
defadd(a, b):return a + b# 查看字节码import disdis.dis(add)
输出:
2 0 LOAD_FAST 0 (a) 2 LOAD_FAST 1 (b) 4 BINARY_ADD 6 RETURN_VALUE
这不是机器码。是 Python 虚拟机能理解的指令。
为什么要有字节码?
- 跨平台:字节码在任何有 Python 的机器上都能运行
- 简化虚拟机:虚拟机只需要理解字节码,不需要理解源代码
Python 虚拟机(PVM)
PVM 是一个栈机器。
# 计算 1 + 2result = 1 + 2
执行过程:
1. LOAD_CONST 1 # 栈: [1]2. LOAD_CONST 2 # 栈: [1, 2]3. BINARY_ADD # 弹出 1 和 2,压入 3。栈: [3]4. STORE_NAME # 存储到变量 result
栈机器简单、可移植,但比寄存器机器慢。
这也是 Python 性能不如 C 的原因之一。
全局解释器锁(GIL)
GIL 是 Python 最大的争议。
是什么: 一个互斥锁,确保同一时刻只有一个线程执行 Python 字节码。
为什么存在: Python 的内存管理不是线程安全的。GIL 简化了实现。
影响: 多线程无法利用多核 CPU。
# 这段代码在 8 核机器上只能用满 1 个核import threadingdefcpu_task(): sum(range(10_000_000))threads = [threading.Thread(target=cpu_task) for _ in range(8)]for t in threads: t.start()for t in threads: t.join()
解决方案:
- 异步 I/O:
asyncio,适合 I/O 密集型
# 多进程绕过 GILfrom multiprocessing import Pooldefcpu_task(n):return sum(range(n))with Pool(8) as p: results = p.map(cpu_task, [10_000_000] * 8)
垃圾回收
Python 使用引用计数 + 循环检测。
import sysa = []print(sys.getrefcount(a)) # 2 (a + getrefcount 的参数)b = aprint(sys.getrefcount(a)) # 3del bprint(sys.getrefcount(a)) # 2
引用计数实时回收,但无法处理循环引用:
# 循环引用a = []b = []a.append(b)b.append(a)# 引用计数永远不会为 0
循环检测器定期扫描,清理这类孤立对象。
设计思想:Python 之禅
在 Python 解释器里输入 import this:
The Zen of Python, by Tim Peters(Python 之禅,作者 Tim Peters)Beautiful is better than ugly.优美胜于丑陋。Explicit is better than implicit.显式胜于隐式。Simple is better than complex.简单胜于复杂。Complex is better than complicated.复杂胜于繁琐。Flat is better than nested.扁平胜于嵌套。Sparse is better than dense.稀疏胜于密集。Readability counts.可读性很重要。...
这不是装饰。这是 Python 设计的核心原则。
1. 可读性至上
# Python 风格for user in users:if user.is_active: send_email(user)# 某些语言的风格users.filter(u => u.is_active).forEach(u => sendEmail(u));
显式循环比函数式链更"啰嗦",但更易读。
2. 只有一种明显的方式
Perl 的口号是"There's More Than One Way To Do It"。
Python 反其道而行。
# 获取索引for i, item in enumerate(items):pass# 而不是for i in range(len(items)): item = items[i]
enumerate 是"Pythonic"的方式。其他方式也能工作,但不被鼓励。
3. 电池内置
Python 标准库非常丰富:
import json # JSON 处理import sqlite3 # 数据库import http.server # HTTP 服务器import email # 邮件处理import zipfile # 压缩文件import csv # CSV 处理import logging # 日志import unittest # 单元测试import argparse # 命令行参数import asyncio # 异步 I/O
开箱即用,不需要到处找依赖。
4. 鸭子类型
"如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子。"
defgreet(obj):# 不检查类型,直接调用 print(obj.name)classPerson: name = "Alice"classDog: name = "Buddy"greet(Person()) # Alicegreet(Dog()) # Buddy
不强制类型,只要求行为。这让 Python 代码非常灵活。
5. EAFP vs LBYL
EAFP:Easier to Ask for Forgiveness than Permission(先做,错了再处理)
LBYL:Look Before You Leap(先检查,再行动)
# LBYL(其他语言常见)if hasattr(obj, 'name'): print(obj.name)else: print("No name")# EAFP(Python 风格)try: print(obj.name)except AttributeError: print("No name")
Python 鼓励 EAFP,因为更简洁,避免竞态条件。
Python 的局限
诚实地说,Python 不是万能的。
1. 性能
Python 比 C 慢 10-100 倍。
# 计算密集型任务total = sum(range(10_000_000)) # 约 0.3 秒
等价的 C 代码约 0.01 秒。
解决: 用 NumPy、Cython、或直接写 C 扩展。
2. 移动开发
Python 在 iOS 和 Android 上几乎不存在。
想写移动应用?选 Swift/Kotlin/Flutter/React Native。
3. 嵌入式
MicroPython 存在,但不是主流。
嵌入式开发还是 C/C++/Rust 的天下。
4. 高并发服务
GIL 限制了多线程性能。
需要每秒处理 10 万请求?考虑 Go、Rust、Erlang。
总结
Python 不是一个"完美"的语言。
它有性能问题,有 GIL,有动态类型的坑。
但它做到了一件事:降低编程的门槛。
新手可以在第一天写出有用的东西。专家可以在一个下午搭出原型。这正是 Guido 在 1989 年想要的结果。
30 年后,这个目标依然成立。
技术来来去去,但"让事情变简单"永远不会过时。
最好的语言不是最快的,而是让你最有效率的。