杰瑞科技汇

Python2与Python3核心差异有哪些?

Python 3 是现在和未来的标准,而 Python 2 已在 2025 年 1 月 1 日官方停止支持,对于任何新项目,都应该毫不犹豫地选择 Python 3。

Python2与Python3核心差异有哪些?-图1
(图片来源网络,侵删)

下面我将从几个核心方面详细阐述它们之间的区别。


核心语法差异

a) print 语句

这是最著名、最直观的区别之一。

  • Python 2: print 是一个语句,不是函数。

    # 输出字符串
    print "Hello, World!"
    # 输出多个值,用空格分隔
    print "Hello", "World"
    # 如果想抑制末尾的换行符,需要在末尾加逗号
    print "Hello,",
    print "World"
  • Python 3: print 是一个函数,必须使用括号。

    Python2与Python3核心差异有哪些?-图2
    (图片来源网络,侵删)
    # 输出字符串
    print("Hello, World!")
    # 输出多个值,用空格分隔
    print("Hello", "World")
    # 抑制末尾的换行符,使用 end 参数
    print("Hello", end=" ")
    print("World")

b) 整数除法

这是另一个非常重要的变化,直接影响数学计算。

  • Python 2: 当两个整数相除时,结果会自动截断为整数(向下取整)。

    >>> 5 / 2
    2
    >>> -5 / 2
    -3  # 注意,是向下取整
  • Python 3: 执行真除法,结果总是浮点数,而 执行整数除法(向下取整)。

    >>> 5 / 2
    2.5
    >>> -5 / 2
    -2.5
    # 使用 // 进行整数除法
    >>> 5 // 2
    2
    >>> -5 // 2
    -3

c) Unicode 支持

这是两者在处理文本上的根本性区别。

Python2与Python3核心差异有哪些?-图3
(图片来源网络,侵删)
  • Python 2: 有两种字符串类型:

    • str: 字节串,是机器的底层表示。
    • unicode: Unicode 字符串,是抽象的文本表示。 默认情况下,"你好" 是一个 str(字节串),如果包含非 ASCII 字符,很容易引发编码错误。
  • Python 3: 有两种字符串类型:

    • str: Unicode 字符串,是文本的默认表示。
    • bytes: 字节串,用于处理二进制数据。 默认情况下,"你好" 就是一个 str(Unicode 字符串),处理多语言文本更加自然和简单。

d) xrange vs range

  • Python 2:

    • range(): 会立即生成一个包含所有数字的列表,当范围很大时,会占用大量内存。
    • xrange(): 返回一个 xrange 对象,它是一个序列对象,在迭代时才生成数字,内存效率极高。
  • Python 3:

    • range() 的行为被修改为等同于 Python 2 的 xrange(),它返回的是一个 range 对象(一个不可变的序列),内存效率高。
    • xrange() 这个名称被移除了。
    # Python 3
    r = range(1000000)  # 这不会立即创建一个包含100万个数字的列表
    for i in r:          # 在迭代时,数字才被按需生成
        pass

e) 异常处理语法

  • Python 2: 捕获异常和获取异常值的方式。

    try:
        # 尝试执行的代码
        1 / 0
    except ZeroDivisionError, e:  # 注意这里的逗号
        print("Error: %s" % e)
  • Python 3: 使用了更现代、更清晰的 as 关键字。

    try:
        # 尝试执行的代码
        1 / 0
    except ZeroDivisionError as e:  # 使用 as 关键字
        print("Error: %s" % e)

f) 迭代器 .next() 方法

  • Python 2: 迭代器的下一个元素是通过 .next() 方法获取的。

    my_list = [1, 2, 3]
    it = iter(my_list)
    print(it.next())  # 输出 1
  • Python 3: .next() 方法被内置函数 next() 替代,这样所有可迭代对象都可以使用统一的方式。

    my_list = [1, 2, 3]
    it = iter(my_list)
    print(next(it))  # 输出 1

库和模块差异

  • urllib 重构:

    • Python 2: urllib, urllib2, urlparse 等模块功能分散,使用起来比较混乱。
    • Python 3: 将这些模块重构并统一为 urllib.request, urllib.parse, urllib.error 等,结构更清晰。
  • configparser:

    • Python 2: 模块名为 ConfigParser(大小写混合)。
    • Python 3: 模块名统一为小写 configparser
  • queue:

    • Python 2: 队列模块名为 Queue(大写 Q)。
    • Python 3: 模块名统一为小写 queue

其他重要区别

特性 Python 2 Python 3
默认编码 源码文件默认是 ASCII 源码文件默认是 UTF-8
关键字 exec 是一个语句 exec 是一个函数,exec(...)
input() vs raw_input() input() 会将输入作为表达式执行(不安全),raw_input() 总是返回字符串 input() 总是返回字符串,raw_input() 被移除
列表推导式作用域 列表推导式会泄露循环变量到外部作用域 列表推导式有自己独立的作用域,不会泄露变量
八进制字面量 0755 (前导零) 0o755 (前导 0o)

如何从 Python 2 迁移到 Python 3?

由于代码不兼容,手动修改代码是繁琐且容易出错的,社区提供了强大的自动化工具来辅助迁移。

最著名的工具是 2to3,它是一个 Python 程序,可以读取你的 Python 2 代码,自动将其转换为 Python 3 代码。

使用步骤:

  1. 安装 lib2to3 工具(Python 自带)。
  2. 在命令行运行:
    # 将 my_script.py 转换为 my_script.py.bak(备份)并生成新的 my_script.py
    2to3 -w my_script.py
  3. 重要: 2to3 不能解决所有问题(特别是依赖于特定库行为的代码),转换后仍然需要人工测试和修复。

对于大型项目,可以使用 modernizefuturize 等更智能的工具,它们可以提供“向前兼容”的代码,让你的代码同时在 Python 2 和 Python 3 环境下运行(作为过渡方案)。


方面 Python 2 (旧版) Python 3 (新版)
状态 已停止支持 当前和未来标准
print 语句 print "..." 函数 print("...")
除法 是整数除法 是真除法, 是整数除法
字符串 str (字节) 和 unicode (文本) str (Unicode 文本) 和 bytes (字节)
迭代器 .next() 方法 next() 内置函数
异常捕获 except Exception, e: except Exception as e:
xrange 存在,内存高效 已移除,range() 具备其功能
模块名和结构较混乱 重构和统一,更清晰

除非你需要维护一个非常古老的、无法迁移的 Python 2 项目,否则永远应该选择 Python 3,它修复了 Python 2 的许多设计缺陷,提供了更清晰、更一致、更强大的语言特性,并且拥有更活跃的社区和更丰富的现代库支持。

分享:
扫描分享到社交APP
上一篇
下一篇