简介
Python 3于2008年12月发布,带来了许多语法改进和新特性。本页面详细对比Python 2和Python 3之间的主要语法差异,帮助开发者理解并顺利迁移代码。
注意:Python 2已于2020年1月1日停止官方支持,建议所有项目迁移至Python 3。
1. 打印语句
Python 2
print "Hello, World!"
print "多行输出", "不换行"
print # 空行
Python 3
print("Hello, World!")
print("多行输出", "不换行")
print() # 空行
在Python 3中,print从语句变成了函数,必须使用括号。这使得语法更加一致,并且可以更灵活地使用关键字参数。
Python 3中可以使用关键字参数:print("Hello", end=" ")来控制输出。
2. 整数除法
Python 2
5 / 2 # 结果: 2 (整数除法)
5 / 2.0 # 结果: 2.5 (浮点除法)
5 // 2 # 结果: 2 (地板除法)
Python 3
5 / 2 # 结果: 2.5 (浮点除法)
5 // 2 # 结果: 2 (地板除法)
5 / 2.0 # 结果: 2.5 (浮点除法)
Python 3中,/运算符总是执行浮点除法,而不管操作数类型。如果需要整数除法,应使用//运算符。
这一变化使得除法行为更加直观和一致,符合数学直觉。
3. Unicode处理
Python 2
# 默认字符串是ASCII编码
s = "你好" # 可能导致编码问题
# Unicode字符串需要前缀u
u = u"你好" # Unicode字符串
# 字节字符串
b = "你好".encode('utf-8')
Python 3
# 默认字符串是Unicode编码
s = "你好" # 正常Unicode字符串
# 字节字符串需要前缀b
b = b"hello" # 只能包含ASCII字符
# 编码为字节
bytes_data = "你好".encode('utf-8')
Python 3中,所有字符串默认为Unicode字符串,这解决了Python 2中处理非ASCII文本的许多问题。
Python 3明确区分了文本字符串(str)和字节序列(bytes),使编码处理更加清晰。
4. 异常处理
Python 2
try:
do_something()
except Exception, e:
print e
# 多异常捕获
try:
do_something()
except (TypeError, ValueError), e:
print e
Python 3
try:
do_something()
except Exception as e:
print(e)
# 多异常捕获
try:
do_something()
except (TypeError, ValueError) as e:
print(e)
Python 3使用as关键字捕获异常,语法更加清晰。
这种语法更符合Python的整体设计理念,避免了逗号可能带来的歧义。
5. range与xrange
Python 2
# 创建列表
r = range(10) # [0, 1, 2, ..., 9]
# 创建迭代器,更节省内存
x = xrange(10) # xrange对象
for i in xrange(1000000): # 内存高效
pass
Python 3
# 创建迭代器,行为类似Python 2的xrange
r = range(10) # range对象,不是列表
# xrange不再存在
# 转换为列表需要显式操作
l = list(range(10)) # [0, 1, 2, ..., 9]
for i in range(1000000): # 内存高效
pass
Python 3中的range函数返回迭代器而非列表,行为类似Python 2中的xrange,更加内存高效。
xrange函数在Python 3中被移除,因为range已经提供了相同的功能。
6. 迭代器方法
Python 2
it = iter([1, 2, 3])
it.next() # 返回1
it.next() # 返回2
# 实现迭代器
class MyIterator:
def __iter__(self):
return self
def next(self):
# 实现逻辑
Python 3
it = iter([1, 2, 3])
next(it) # 返回1
next(it) # 返回2
it.__next__() # 返回3
# 实现迭代器
class MyIterator:
def __iter__(self):
return self
def __next__(self):
# 实现逻辑
Python 3中,迭代器的next()方法改名为__next__(),与其他特殊方法的命名更加一致。
推荐使用内置函数next(iterator)而不是调用迭代器的方法。
7. 输入函数
Python 2
# 获取原始输入字符串
name = raw_input("请输入姓名: ")
# 获取并计算输入的Python表达式
result = input("请输入表达式: ")
# 输入 1+2 会返回 3
# 有安全风险
Python 3
# 获取输入字符串
name = input("请输入姓名: ")
# 要计算表达式,需要显式使用eval
expr = input("请输入表达式: ")
result = eval(expr) # 谨慎使用eval
Python 3中,raw_input()被移除,input()的行为变为获取字符串输入(类似Python
2的raw_input())。
这一变化提高了安全性,避免了Python 2中input()可能导致的代码注入风险。
8. 类语法
Python 2
# 经典类
class OldClass:
def method(self):
pass
# 新式类
class NewClass(object):
def method(self):
pass
Python 3
# 所有类都是新式类
class MyClass:
def method(self):
pass
# 显式继承object是可选的
class MyClass2(object):
def method(self):
pass
Python 3中,所有类默认都是新式类,不再需要显式继承object。
新式类提供了更一致的方法解析顺序、更好的属性查找机制和对描述符的支持。
9. 不等运算符
Python 2
# 两种不等运算符
if a != b:
print "不相等"
if a <> b: # 另一种不等运算符
print "不相等"
Python 3
# 只有一种不等运算符
if a != b:
print("不相等")
# <> 运算符已被移除
Python 3移除了<>不等运算符,只保留!=,使语法更加一致。
这减少了语法的冗余性,符合Python"用一种方法做一件事"的设计理念。
10. 字典方法
Python 2
d = {'a': 1, 'b': 2}
# 返回列表
keys = d.keys() # ['a', 'b']
values = d.values() # [1, 2]
items = d.items() # [('a', 1), ('b', 2)]
# 迭代
for k in d.iterkeys():
print k
Python 3
d = {'a': 1, 'b': 2}
# 返回视图对象,而非列表
keys = d.keys() # dict_keys(['a', 'b'])
values = d.values() # dict_values([1, 2])
items = d.items() # dict_items([('a', 1), ('b', 2)])
# 转换为列表
keys_list = list(d.keys())
# iterkeys()等方法已移除
for k in d.keys(): # 或直接 for k in d:
print(k)
Python
3中,字典方法.keys()、.values()和.items()返回视图对象而非列表,这些视图对象会动态反映字典的变化。
Python 2中的.iterkeys()、.itervalues()和.iteritems()方法在Python
3中被移除,因为常规方法已经返回迭代器。