核心差异概览
| 特性 | Python 2 | Python 3 | 说明 |
|---|---|---|---|
print 语句 |
print "Hello, World!" (是语句) |
print("Hello, World!") (是函数) |
Python 3 将 print 变成了一个内置函数,必须使用括号。 |
| 整数除法 | 5 / 2 结果是 2 (整数除法) |
5 / 2 结果是 5 (真除法) |
Python 3 的除法行为更符合数学直觉。 用于整数除法。 |
range() vs xrange() |
range() 返回列表,xrange() 返回迭代器 |
只有 range(),它返回一个类似 xrange() 的迭代器 |
Python 3 的 range() 更节省内存,尤其是在处理大范围数字时。 |
| Unicode 支持 | str 是字节,unicode 是文本 |
str 是 Unicode 文本,bytes 是字节 |
Python 3 默认使用 Unicode,处理文本更直观。 |
| 函数参数 | 支持位置参数、默认参数、*args、**kwargs |
与 Python 2 相同,但增加了仅位置参数 | Python 3.8+ 引入了 来指定仅位置参数。 |
| 函数注解 | 不支持 | 支持 (def func(a: int) -> float:) |
提供了一种为函数参数和返回值添加类型提示的方式,静态检查工具(如 MyPy)可以利用它。 |
print 的演变:从语句到函数
这是最直观、也是新手最容易混淆的区别。

Python 2
在 Python 2 中,print 是一个关键字,一个语句,而不是函数,它不需要括号。
# Python 2 print "Hello, Python 2!" # 直接打印字符串 print "Hello", "World" # 默认用空格分隔多个参数 print "Hello", "World", # 末尾的逗号可以阻止换行
Python 3
在 Python 3 中,print 被改造成了一个内置函数,必须使用括号,这使得 print 的行为与其他函数保持一致,并且可以像其他函数一样使用 end 和 sep 等参数。
# Python 3
print("Hello, Python 3!") # 像调用普通函数一样
print("Hello", "World") # 默认用空格分隔
print("Hello", "World", end=" ") # 使用 end 参数指定结束符,不换行
为什么这个改变很重要?
将 print 变成函数,使其更灵活,可以像其他对象一样传递、赋值给变量等。
# Python 3
log_to_file = print # 将 print 函数赋值给另一个变量
log_to_file("This message will be printed to the console.")
整数除法 ( vs )
Python 2 和 Python 3 在处理整数除法上有根本性的不同。

Python 2
在 Python 2 中,除法运算符 的行为取决于操作数的类型:
- 如果两个操作数都是整数,执行整数除法(截断小数部分)。
- 如果至少有一个操作数是浮点数,执行真除法(保留小数部分)。
# Python 2 >>> 5 / 2 2 # 5 和 2 都是整数,结果是整数 2 >>> 5.0 / 2 2.5 # 5.0 是浮点数,结果是浮点数 2.5 >>> 5 / 2.0 2.5 # 2.0 是浮点数,结果是浮点数 2.5
Python 3
在 Python 3 中,除法运算符 始终执行真除法,无论操作数是什么类型。
- 要进行整数除法,必须使用 运算符。
# Python 3 >>> 5 / 2 2.5 # 始终是真除法 >>> 5.0 / 2 2.5 # 始终是真除法 >>> 5 // 2 2 # 使用 // 进行整数除法
这个改变使得代码更清晰、更符合数学直觉,减少了因类型不同而导致的意外行为。
range() 和 xrange()
Python 2
Python 2 提供了两个生成整数序列的函数:
range(n): 生成一个包含从 0 到 n-1 的所有整数的列表,n 很大,会占用大量内存。xrange(n): 生成一个 xrange 对象,这是一个序列类型,但它不会在内存中一次性生成所有数字,而是在迭代时动态生成,这非常节省内存。
# Python 2
# 创建一个包含 100 万个数字的列表,会占用大量内存
large_list = range(1000000)
# 创建一个 xrange 对象,几乎不占用额外内存
efficient_range = xrange(1000000)
# 可以像列表一样迭代,但它本身不是列表
for i in efficient_range:
pass
Python 3
Python 3 移除了 range() 和 xrange() 的区别,它只保留了 range(),但它的行为和 Python 2 的 xrange() 完全一样:返回一个不可变的、类似序列的 range 对象,它在迭代时动态生成数字,非常节省内存。
# Python 3
# range() 返回的是一个 range 对象,而不是列表
r = range(5)
print(r)
# 输出: range(0, 5)
# 可以迭代
for i in r:
print(i)
# 输出: 0, 1, 2, 3, 4
# 如果需要像 Python 2 那样得到一个列表,需要显式转换
my_list = list(range(5))
print(my_list)
# 输出: [0, 1, 2, 3, 4]
函数定义和参数(更高级的用法)
基本的函数定义在 Python 2 和 3 中是相同的,但 Python 3 引入了一些更强大的特性。
基本定义(相同)
# Python 2 和 Python 3 都支持
def greet(name, greeting="Hello"):
"""Greets a person."""
return f"{greeting}, {name}!" # 注意:f-string 是 Python 3.6+ 的特性
print(greet("Alice"))
print(greet("Bob", greeting="Hi"))
函数注解 (Type Hints)
Python 3 引入了函数注解,这是一种可选的静态类型提示机制,用于告诉代码(和人类)函数期望的参数类型和返回类型,它不会在运行时进行类型检查。
# Python 3
def add(a: int, b: int) -> int:
"""Adds two integers and returns the sum."""
return a + b
result = add(10, 20)
print(result) # 输出: 30
# 注解只是元数据,不会阻止你传入错误类型
# result = add("10", "20") # 这在运行时是允许的,但静态检查工具会报错
仅位置参数 (Positional-Only Arguments)
Python 3.8 引入了一个新语法 ,用于强制某些参数必须通过位置传递,而不能通过关键字传递。
# Python 3.+
def get_data(url, /, timeout=10, *, cache=True):
"""
url: 必须通过位置传递 (get_data('http://example.com'))
timeout: 可以通过位置或关键字传递 (get_data('http://example.com', 5) 或 get_data('http://example.com', timeout=5))
cache: 必须通过关键字传递 (get_data('http://example.com', cache=False))
"""
print(f"URL: {url}, Timeout: {timeout}, Cache: {cache}")
# 正确用法
get_data("http://a.com")
get_data("http://a.com", 5)
get_data("http://a.com", timeout=5)
get_data("http://a.com", 5, cache=False)
# 错误用法
# get_data(url="http://a.com") # TypeError: got some positional-only arguments passed as keyword arguments: 'url'
迁移建议:如何将 Python 2 代码迁移到 Python 3
- 使用
2to3工具:Python 官方提供了一个名为2to3的脚本,它可以自动将大部分 Python 2 代码转换为 Python 3 代码,你可以尝试运行python -m 2to3 your_script.py。 - 手动检查和修改:
2to3并非万能,特别是对于一些依赖库的特定逻辑,你需要手动检查:- 所有
print语句是否都加上了括号。 - 所有除法运算 是否符合你的预期,必要时使用 。
- 处理字符串和字节时,确保编码正确,从文件读取或网络请求获取的字节数据需要解码为字符串(
data.decode('utf-8'))。 xrange替换为range。
- 所有
- 使用
six库:如果你的代码需要同时兼容 Python 2 和 Python 3(过渡期策略),可以使用six这样的库,它提供了一些兼容性函数和工具。
| 领域 | Python 2 | Python 3 | 关键影响 |
|---|---|---|---|
print |
print "..." (语句) |
print("...") (函数) |
更一致、更灵活 |
| 除法 | 根据类型决定行为 | 总是真除法, 是整数除法 | 更符合直觉,减少错误 |
range |
range (列表), xrange (迭代器) |
range (迭代器) |
内存效率更高 |
| 函数 | 基础功能 | 注解、仅位置参数等高级特性 | 更强大、更具可读性 |
Python 3 在函数设计和核心语言行为上进行了大量改进,使其更现代化、更安全、更易于使用,如果你正在开始一个新项目,请毫不犹豫地选择 Python 3。
