Python 3 是 Python 的未来,而 Python 2 已经停止官方支持。 所有新项目都应该使用 Python 3。

下面我将从几个核心方面详细解释它们的区别。
核心区别概览
| 特性 | Python 2 | Python 3 | 说明 |
|---|---|---|---|
| 默认编码 | ASCII | UTF-8 | 这是最根本的区别之一,影响了字符串处理。 |
| 字符串类型 | str (字节串), unicode (文本串) |
str (文本串), bytes (字节串) |
Python 3 统一和简化了字符串模型。 |
| 打印语句 | print "Hello" |
print("Hello") |
print 从一个语句变成了一个函数。 |
| 整数除法 | 5 / 2 结果是 2 |
5 / 2 结果是 5 |
Python 3 的除法行为更符合数学直觉。 |
| 异常处理 | except Exception, e: |
except Exception as e: |
语法更清晰,与其它主流语言(如 Java, C++)保持一致。 |
xrange() |
xrange() |
移除 | range() 在 Python 3 中实现了 xrange() 的惰性求值功能,性能更好。 |
input() vs raw_input() |
input() (不安全), raw_input() |
input() (统一且安全) |
Python 3 的 input() 等同于 Python 2 的 raw_input()。 |
迭代器/next() |
.next() |
next() |
将 .next() 方法改为内置函数 next(),更符合 Pythonic 风格。 |
super() |
super(Child, self).method() |
super().method() |
语法更简洁,不再需要显式传递子类和实例。 |
asyncio |
不存在 | 内置支持 | 原生支持异步编程,是现代 Python 的重要特性。 |
| 标准库 | 较旧,部分库已过时 | 更新、现代化,大量改进 | Python 3 的标准库更强大、更完善。 |
详细解释关键区别
字符串和编码 (最核心的区别)
这是两者之间最根本、也是最容易出问题的区别。
-
Python 2:
str: 字节串,本质上是字节的序列,默认使用 ASCII 编码。unicode: 文本串,可以表示任何 Unicode 字符。- 问题: 当处理非英文字符(如中文)时,你必须非常小心地在
str和unicode之间进行转换,如果忘记解码或编码,程序很容易抛出UnicodeDecodeError或UnicodeEncodeError。
# Python 2 s = "你好" # 这是一个 str (字节串),在内存中可能不是你期望的样子 u = u"你好" # 这是一个 unicode # 必须显式编码 s_to_u = s.decode('utf-8') u_to_s = u.encode('utf-8') -
Python 3:
(图片来源网络,侵删)str: 文本串,默认使用 UTF-8 编码,可以表示任何 Unicode 字符,这是你日常编码时主要使用的类型。bytes: 字节串,是str的一个不可变序列,用于处理二进制数据(如文件读写、网络通信)。- 优势: 模型非常清晰,你处理文本就用
str,处理二进制数据就用bytes,转换是显式的,但设计更合理。
# Python 3 s = "你好" # 这是一个 str (文本串),内部是 Unicode b = b"hello" # 这是一个 bytes # 显式转换 s_to_b = s.encode('utf-8') b_to_s = b.decode('utf-8')
print 语句 vs print() 函数
这是一个语法上的巨大改变,影响了所有 Python 程序员。
-
Python 2:
print是一个语句,不是函数。# Python 2 print "Hello, World" print "Hello", "World" # 输出: Hello World (带空格) print >> sys.stderr, "Error!" # 重定向输出
-
Python 3:
print是一个函数,必须使用括号。# Python 3 print("Hello, World") print("Hello", "World") # 输出: Hello World (带空格) # 重定向需要导入文件对象 import sys print("Error!", file=sys.stderr)好处:
print作为函数,可以像其他函数一样,拥有更灵活的参数(如sep,end,file),并且可以用于函数式编程(map(print, my_list))。
(图片来源网络,侵删)
整数除法
这个改变让数学运算更直观,但也让从 Python 2 迁移的旧代码成为错误的主要来源。
-
Python 2: 当两个整数相除时,结果会自动截断为整数。
# Python 2 >>> 5 / 2 2 >>> 5 / 2.0 # 如果有一个操作数是浮点数,结果就是浮点数 2.5
-
Python 3: 总是执行“真除法”,返回浮点数,要获取整数除法的结果,需要使用 运算符。
# Python 3 >>> 5 / 2 2.5 >>> 5 // 2 # 整数除法 2
好处: 行为符合数学定义,减少了因类型隐式转换带来的意外。
异常处理语法
这个改变主要是为了代码的清晰度和一致性。
-
Python 2: 使用逗号来分隔异常类型和变量。
# Python 2 try: result = 10 / 0 except ZeroDivisionError, e: # 注意这里的逗号 print("Error:", e) -
Python 3: 使用
as关键字,与 C++、Java、C# 等语言保持一致。# Python 3 try: result = 10 / 0 except ZeroDivisionError as e: # 使用 as 关键字 print("Error:", e)
input() 和 raw_input()
这个改变让 Python 的输入函数更安全、更符合直觉。
-
Python 2:
raw_input(): 从标准输入读取一行,并将其作为字符串返回。input(): 从标准输入读取一行,并将其作为Python 表达式进行求值,这非常危险!如果用户输入恶意代码,它会被执行。# Python 2 # 安全 name = raw_input("What's your name? ") # 危险! age = input("How old are you? ") # 如果用户输入 "os.system('rm -rf /')",你的硬盘就没了
-
Python 3:
input(): 统一了功能,等同于 Python 2 的raw_input(),它总是返回一个字符串,这使得输入函数既安全又简单。# Python 3 name = input("What's your name? ") # 总是返回字符串 age_str = input("How old are you? ") age = int(age_str) # 如果需要数字,需要手动转换
为什么会有 Python 3?—— 设计哲学
Python 3 的出现是为了解决 Python 2 中的一些历史遗留问题,其核心设计理念是:
- “显式优于隐式” (Explicit is better than implicit): 编码和解码、异常捕获、迭代器访问等操作都变得更加显式,减少了魔法行为。
- 一致性: 整数除法、异常处理语法等变得更统一、更符合直觉。
- 现代化: 移除了过时的特性(如
<>代替 ),引入了现代编程概念(如asyncio、类型提示)。 - 修复设计缺陷: 比如字符串模型、迭代器协议等。
如何选择?
毫无疑问,请选择 Python 3。
- 新项目: 必须使用 Python 3,不要再使用 Python 2 开发任何新东西。
- 维护旧项目: 如果你在维护一个基于 Python 2 的项目,你需要评估迁移的成本和收益,由于 Python 2 已在 2025 年 1 月 1 日停止支持,不再有安全补丁,迁移是必然的,可以使用
2to3等工具辅助迁移,但通常需要大量手动调整。
| Python 2 | Python 3 | |
|---|---|---|
| 状态 | 已死 (EOL) | 活生生的未来 |
| 核心 | 字节串和文本串分离,易混淆 | 统一的字符串模型,清晰直观 |
| 语法 | print 语句, except E, e |
print() 函数, except E as e |
| 运算 | 整数除法 | 真除法, 整数除法 |
| 输入 | input() 危险, raw_input() 安全 |
input() 安全且统一 |
| 库 | 逐渐过时 | 现代化、功能强大 |
从 Python 2 到 Python 3 的迁移是痛苦的,但它让这门语言变得更强大、更安全、更易于使用,对于任何新学习者或新项目来说,Python 3 是唯一的选择。
