当前位置:网站首页 > Python数据科学 > 正文

Python各版本的差异总结_python各版本之间的区别

版本

  • Python 是什么?
    • 1989 年圣诞节期间,荷兰人 Guido van Rossum 在参与研发了 ABC 语言之后,开始研发一种更好的脚本语言,取名为 Python 。
      • 取名为 Python 是为了致敬英国的喜剧团体 Monty Python 。
      • 与传统编程语言相比,Python 的优点为:简单易懂、通用性强
    • 他成立了 Python 软件基金会,召集开源社区的志愿者,共同研发 Python ,主要工作为修复漏洞、增加新语法。
      • 官方网站为 https://www.python.org/
      • 大概每年发布 Python 的一个新版本,每次增加两三种新语法。
  • Python 解释器是什么?
    • 按照 Python 语法编写的代码,必须交给一种称为 Python interpreter 的软件来执行,中文名为 Python 解释器。
    • 一个电脑上,安装了什么版本的 Python 解释器,则能运行相同版本的 Python 代码,也能运行更老版本的 Python 代码。
      • 例如:如果安装了 version = 3.6 的 Python 解释器,则通常可以运行 version ≤ 3.6 的 Python 代码,通常不能运行 version > 3.6 的 Python 代码。
    • 一个电脑上,可以安装多个不同版本的 Python 解释器,从而支持多个版本的 Python 语法。

Python2

  • Python2.0 :于 2000 年发布 https://www.python.org/downloads/release/2.0/
  • Python2.1 ~ Python2.6 略
  • Python2.7 :于 2010 年发布 https://www.python.org/downloads/release/python-270/ ,这是 Python2 的最后一个子版本。

Python3

  • 从 Python 2.x 到 Python 3.x 是一个大版本升级,有很多不向下兼容的差异。
    • 因此, Python2.x 的解释器,通常不能运行 Python3.x 语法的代码。反之亦然,Python3.x 的解释器,通常不能运行 Python2.x 语法的代码。
    • 2020 年,Python 官方宣布停止维护 Python2.x ,不再修复漏洞。换句话说,这些旧版本的代码,都超过了保质期。
差异点 Python2 Python3
输出方式 用 print 关键字,例如 print "Hello" 用 print() 函数,例如 print("Hello")
输入方式 用 raw_input() 函数 用 input() 函数
字符串的编码格式 默认采用 ASCII 默认采用 Unicode
源文件的编码格式 默认采用 ASCII ,因此使用中文时要在源文件开头加上一行 # -*- coding: utf-8 -*- 默认采用 uft-8
格式化字符串的方式 用 % 符号,例如 "Hello %s" % ("World") 用 str.format() 方法,例如 "Hello {}".format('World')
  • Python3.0 :于 2008 年发布 https://www.python.org/download/releases/3.0/
  • Python3.1 ~ Python3.3 略

Python3.4

  • 于 2014 年发布:https://www.python.org/downloads/release/python-340/
  • 采用 pip 作为 Python 包的默认安装方式。
  • 增加标准库 pathlib ,用于按面向对象的方式操作文件路径。如下:
    >>> from pathlib import Path >>> p = Path('/root/test/1.py') >>> p.name '1.py' >>> p.suffix '.py' >>> p.exists() False 
  • 增加标准库 enum ,用于定义枚举类。如下:
    >>> from enum import Enum >>> >>> class Test(Enum): ... a = 1 ... b = 2 ... c = 3 ... >>> Test.a <Test.a: 1> >>> Test['a'] # 可按名字索引 <Test.a: 1> >>> list(Test) # 可迭代 [<Test.a: 1>, <Test.b: 2>, <Test.c: 3>] 
  • 增加标准库 asyncio ,用于实现异步 IO 。它取代了旧的 asyncore 库。
  • 增加标准库 statistics ,提供了求平均值、中位数、方差等运算的函数。
  • 增加标准库 tracemalloc ,用于跟踪内存分配的情况,方便调试。

Python3.5

  • 于 2015 年发布:https://www.python.org/downloads/release/python-350/
  • 扩展了迭代拆包运算符 * 、字典拆包运算符 的语法。
    • 可以在元组、列表、集合、字典表达式中使用:
      >>> *range(4) SyntaxError: can't use starred expression here >>> *range(4), 4 (0, 1, 2, 3, 4) >>> [*range(4), 4] [0, 1, 2, 3, 4] >>> { 
             'a': 1, { 
             'b': 2}} { 
             'a': 1, 'b': 2} 
    • 可以同时多次使用:
      >>> print(*[1], *[2], *{ 
             'c': 3}) 1 2 c >>> dict({ 
             'a': 1}, { 
             'b': 2}) { 
             'a': 1, 'b': 2} 
  • 增加语法:使用 Python2 风格的百分号 % 来格式化字符串。
    >>> '%a' % 3.14 '3.14' >>> b'%a' % 3.14 b'3.14' 
  • 增加关键字 asyncawait ,用于定义协程:
    async def read_db(db): data = await db.fetch('SELECT ...') 
  • 增加语法:类型注释(type annotations)。
    • 对于函数,可以用冒号 : 添加形参的注释,用 -> 添加返回值的注释。这些注释会存储在函数的 __annotations__ 属性中:
      >>> def fun1(a, b: "字符串或 None", c: int = 0) -> int: ... pass ... >>> fun1.__annotations__ { 
             'b': '字符串或 None', 'c': <class 'int'>, 'return': <class 'int'>} 
    • 对于变量,可以用冒号 : 添加注释:
      >>> x : int # 该语句可以执行,但并不会创建变量 x >>> x NameError: name 'x' is not defined >>> x : int = 1 # 添加类型注释并赋值 >>> x 1 
    • 类型注释可以是任意可执行的表达式。例如:
      >>> x : int # 该注释为一个类型,不会强制类型检查,但可以供 IDE 等工具进行静态类型检查 >>> x : 'Hello' # 该注释为一个 str 值 >>> x : print('Hello') # 该注释为一个语句 Hello 
  • 增加标准库 typing ,定义了一些类型,常用于类型注释。
  • 增加标准库 zipapp ,用于将 Python 脚本打包成可执行的归档文件,扩展名为 .pyz 。

Python3.6

  • 于 2016 年发布:https://www.python.org/downloads/release/python-360/
  • dict 中的元素以前是按 key 顺序存储:
    >>> { 
         2:'', 1:''} { 
         1: '', 2: ''} 

    现在会按插入顺序存储:

    >>> { 
         2:'', 1:''} { 
         2: '', 1: ''} 
  • 增加语法:在数字中插入下划线作为分隔符,提高可读性。
    >>> 1_000_111_000  >>> '{:_}'.format() # 格式化字符串时也可输出下划线 '1_000_000' 
  • 增加语法:给字符串加上前缀 f 时,会将花括号 { } 中的内容当成 Python 代码执行。
    • 这种语法称为 f-string ,常用于格式化字符串,比使用 str.format() 更方便。
    • 可以执行花括号中的代码,嵌入一个值到字符串中:
      >>> a = 1 >>> f'a={ 
               a}' 'a=1' >>> f'a + 1 = { 
               int(a) + 1}' 'a + 1 = 2' >>> f'{ 
              { a }}' # 如果原字符串包含花括号,则需要转义为两个花括号 '{ a }' 
    • 可以填充字符串到指定长度,实现 str.ljust()str.rjust()str.center() 的功能。
      >>> f'{ 
               a :5}' # 用空格填充字符串,至少输出 5 个字符的长度(如果原字符串超过该长度,则不会填充) ' 1' >>> f'{ 
               a :05}' # 用数字 0 填充 '00001' >>> f'{ 
               a :零>5}' # 用任意单个字符填充 '零零零零1' >>> f'{ 
               a :>5}' # 右对齐(默认采用该对齐方式) '1 ' >>> f'{ 
               a :<5}' # 左对齐 '1 ' >>> f'{ 
               a :^5}' # 中心对齐 ' 1 ' 
      完整语法示例:
      >>> content = 1 >>> fill = ' ' >>> align = '>' >>> width = 5 >>> f'{ 
               content :{ 
               fill}{ 
               align}{ 
               width}}' ' 1' 
    • 可以截断字符串到指定长度:
      >>> f'{ 
               "helloworld" :.5}' # 截断字符串,最多输出 5 个字符的长度 'hello' >>> f'{ 
               "helloworld" :10.5}' # 先截断,再填充 'hello ' 
    • 可以转换数字的输出格式:
      >>> f'{ 
               10 :+d}' # 输出为 int 类型,并给非负数添加 + 前缀(否则默认只给负数添加 - 前缀) '+10' >>> f'{ 
               10000 :,d}' # 输出为 int 类型,并用 , 或 _ 作为千位分隔符 '10,000' >>> f'{ 
               10 :f}' # 输出为 float 类型 '10.000000' >>> f'{ 
               10 :e}' # 输出为科学计数法 '1.000000e+01' 
    • 可以转换数字的进制:
      >>> f'{ 
               10 :b}' # 输出为二进制 '1010' >>> f'{ 
               10 :o}' # 输出为八进制 '12' >>> f'{ 
               10 :x}' # 输出为小写的十六进制 'a' >>> f'{ 
               10 :X}' # 输出为大写的十六进制 'A' >>> f'{ 
               10 :#X}' # 加上 # ,则会添加这种进制类型对应的前缀 '0XA' 
  • 支持给类定义 __init_subclass__() 方法,用于初始化子类。如下:
    >>> class Person: ... subclasses = [] ... def __init_subclass__(cls, *args, kwargs): ... super().__init_subclass__(*args, kwargs) ... print('A new subclass is created:', cls) ... cls.subclasses.append(cls) ... >>> class Man(Person): # 创建子类时,会自动执行父类的 __init_subclass__() 方法 ... pass ... A new subclass is created: <class '__main__.Man'> >>> Person.subclasses [<class '__main__.Man'>] 
  • 增加标准库 secrets ,用于生成安全的随机数。
    • 原有的 random 模块生成的随机数可能被预测,安全性低,因此不适合用作密码、加密密钥。

Python3.7

  • 于 2018 年发布:https://www.python.org/downloads/release/python-370/

Python3.8

  • 于 2019 年发布:https://www.python.org/downloads/release/python-380/
  • 增加语法:在 f-string 中可用 {var}{var=} 的格式插入变量的值,方便调试。
    >>> f'{ 
           a}' NameError: name 'a' is not defined # 读取不存在的变量时会报错 >>> a = 1 >>> f'{ 
           a}' '1' >>> f'{ 
           a=}' 'a=1' >>> f'DEBUG: { 
           id(1)=}' # 也可插入函数的返回值,会自动转换成 str 类型 'DEBUG: id(1)=7120' 
  • 增加语法:赋值表达式,用于给表达式中的变量赋值。
    if a := input(): # 相当于先执行 a = input() 再执行 if a: print(a) 
    >>> (a := 0) + 1 1 >>> a 0 
  • 增加语法:定义函数时,可以在形参列表中,插入一个正斜杆 / 、一个星号 *
    • 原本,函数的每个形参,可以接收 positional argument 形式的实参,也可以接收 keyword argument 形式的实参。
      >>> def fun1(a, b=None): ... pass ... >>> fun1(1, 2) >>> fun1(a=1, b=2) 
    • 现在,可以在函数的形参列表中,插入一个正斜杆 / ,表示其左侧的所有形参,只允许接收 positional argument 形式的实参。
      >>> def fun1(a, b=None, /): ... pass ... >>> fun1(1, 2) >>> fun1(a=1, b=2) TypeError: fun1() got some positional-only arguments passed as keyword arguments: 'a, b' 
    • 现在,可以在函数的形参列表中,插入一个星号 * ,表示其右侧的所有形参,只允许接收 keyword argument 形式的实参。
      >>> def fun1(*, a, b=None): ... pass ... >>> fun1(1, 2) TypeError: fun1() takes 0 positional arguments but 2 were given >>> fun1(a=1, b=2) 
    • 更复杂的示例:
      >>> def fun1(a, / , b , *, c, kwargs): ... pass ... >>> fun1() TypeError: fun1() missing 2 required positional arguments: 'a' and 'b' >>> fun1(1, 2) TypeError: fun1() missing 1 required keyword-only argument: 'c' >>> fun1(1, 2, c=3) 
  • 支持在 finally 语句块中使用 continue 关键字。
  • multiprocessing 模块增加一个 SharedMemory 类,用于创建进程之间的共享内存。

Python3.9

  • 于 2020 年发布:https://www.python.org/downloads/release/python-390/
  • dict 类增加合并运算符 |、更新运算符 |=
    • 以前合并字典的方式主要有两种:
      { 
             d1, d2} d1.update(d2) # update() 方法会改变字典的内容 
      例如:
      >>> d1 = { 
             1: 'A'} >>> d2 = { 
             2: 'B'} >>> { 
             d1, d2} { 
             1: 'A', 2: 'B'} >>> d1.update(d2) >>> d1 { 
             1: 'A', 2: 'B'} 
    • 现在可以通过运算符合并字典:
      >>> d1 = { 
             1: 'A'} >>> d2 = { 
             2: 'B'} >>> d1 | d2 # 相当于 {d1, d2} { 
             1: 'A', 2: 'B'} >>> d1 |= d2 # 相当于 d1.update(d2) >>> d1 { 
             1: 'A', 2: 'B'} 
  • str 类增加两个方法 removeprefix()removesuffix() 。如下:
    >>> s = 'Hello' >>> s.rstrip('lo') # 以前的 rstrip() 方法会删除右侧所有匹配的单个字符 'He' >>> s.removesuffix('lo') # 现在的 removesuffix() 方法只会删除匹配的子字符串 'Hel' 

    其原理为:

    def removeprefix(self: str, prefix: str, /) -> str: if self.startswith(prefix): return self[len(prefix):] else: return self[:] 
  • 支持将大部分内置类型的类名用作函数实参,便于声明注释。如下:
    >>> T = type[int] >>> T type[int] >>> list[str] == list[str] True >>> tuple[int, ...] tuple[int, ...] >>> def fun1(x: dict[str, list[int]]): ... pass ... 

Python3.10

  • 于 2021 年发布:https://www.python.org/downloads/release/python-3100/
  • 增加语法:match-case 模式匹配。
  • 增加语法:用 | 运算符连接多个类型,表示 Union 类型。
    >>> int | str # 相当于 typing.Union[int, str] >>> isinstance(1, int|str) # 相当于 isinstance(1, (int, str)) 或 isinstance(1, typing.Union[int, str]) True >>> issubclass(set, int|str) False 
  • 调用 open() 函数时,允许传入参数 encoding='locale' ,等价于 encoding=None ,表示采用当前平台的默认编码格式。

Python3.11

  • 于 2022 年发布:https://www.python.org/downloads/release/python-3110/
  • CPython 解释器优化了加载模块、调用函数等操作,使得 Python3.11 比 Python3.10 的启动速度、运行速度快了 10%~60% 。
  • 增加了标准异常类型 BaseExceptionGroup、ExceptionGroup ,用于将多个异常打包为一组。异常组只能用语法 except* 捕捉。
    • 例:
      >>> try: ... raise ExceptionGroup('异常组1', ([ # 创建异常组时,需要传入组名,和一组异常对象。支持嵌套异常组 ... KeyError('invalid key'), ... TypeError('invalid type'), ... ValueError('invalid value'), ... ])) ... except* TypeError as e: ... print('A') ... except* (TypeError, ValueError) as e: ... print('B') ... A B + Exception Group Traceback (most recent call last): | File "<stdin>", line 2, in <module> | ExceptionGroup: 异常组1 (1 sub-exception) +-+---------------- 1 ---------------- | KeyError: 'invalid key' +------------------------------------ 
    • try 一个异常组时,会从上往下检查各个 except* 。
      • 每个 except* 可以指定一个或多个异常,只要任一异常包含于异常组,则执行该 except* 子句。然后从异常组删除已捕捉的异常,继续匹配之后的 except* 。
      • 一个普通异常最多触发一个 except 子句,而一个异常组可能触发多个 except* 子句。
      • 如果 except* 没有捕捉异常组中的全部异常,则剩下的异常会被抛出。
  • 打印 tracebacks 异常信息时,能更准确地指出引发异常的代码位置。
    • 以前,Python 解释器在执行 Python 程序时,只知道当前执行的是哪条字节码。现在,用两个 uint8_t 数据类型记录每条字节码的起始偏移量、结束偏移量,从而能根据已执行的偏移量,判断目前执行到哪条字节码的哪个位置。
    • 例如编写一个 test.py 脚本:
      1 + 2/0 + 3 
      然后用 python 命令执行:
      [root@CentOS ~]# python test.py Traceback (most recent call last): File "/root/test.py", line 1, in <module> 1 + 2/0 + 3 ~^~ ZeroDivisionError: division by zero 
      倒数第二行信息是 Python3.11 才能打印的,指出这行代码的哪个位置引发了异常。
    • 缺点:
      • pyc 文件、内存中的字节码体积会增大 22% 。不过一般 Python 程序的字节码总共只有几十 MB ,影响小。
      • 用 Python 解释器交互式编程时,没有该功能。

Python3.12

  • 于 2023 年发布:https://www.python.org/downloads/release/python-3120/
  • f-string 增加了几种语法。
    • 花括号 { } 内可包含担任定界符的引号:
      >>> f'array={[1, 'hello']}' "array=[1, 'hello']" 
    • 花括号 { } 内可嵌套多层 f-string :
      >>> f'{ f'{ 
             1+1}'= }' " f'{1+1}'= '2'" 
    • 花括号 { } 内的 Python 代码可跨越多行,可添加注释:
      >>> f'{ 
              ... [1, # one ... 2] # two ... }' '[1, 2]' 
    • 花括号 { } 内可以包含反斜杠 \ ,因此可以包含转义字符:
      >>> f'{'\n'}' '\n' 
  • 简化定义泛型的语法。
    • 旧的语法:
      from typing import TypeVar, Generic T = TypeVar('T') class Test(Generic[T]): def __init__(self, value: T) -> None: pass 
    • 新的语法:
      class Test[T]: def __init__(self, value: T) -> T: ... 
  • 可用 type 关键字定义类型别名:
    type Point = tuple[float, float] 
  • 在 Python 进程中创建子 Python 解释器时,允许每个 Python 解释器不再共享一个 GIL ,而是分别创建一个 GIL 。不过启用该功能需要调用 Cpython 的 API 。

Python3.13

  • 于 2024 年发布:https://www.python.org/downloads/release/python-3130/
  • 改进了交互式终端 shell ,更方便用户使用。
    • 它基于 PyPy 解释器进行工作。
    • 提示符 >>>... 和异常报错,会显示成彩色。
    • 支持多行编辑。如下,一条 Python 语句跨越多行时,可以按方向键,让光标上下移动,想修改哪行就修改哪行。
      >>> print( ... 1 ... ) 
    • 多行编辑时,即使包含空行,也能根据缩进,正确识别一个语句块的结束。
      >>> for i in range(3): ... print(i) ... ... print(i) ... ... 
    • 可按 F1 进入帮助模式。此时输入一个字符串,即可查询相关的帮助文档。按 q 可退出该模式。
    • 可按 F2 进入历史模式,用于查看用户输入的历史命令。此时不会显示 >>>... ,方便鼠标拖动复制。按 q 可退出该模式。
    • 可按 F3 进入粘贴模式。
  • 允许禁用 GIL 全局锁,使得多个 Python 线程可以被 CPU 同时执行,称为自由线程。
    • 这是一个实验性功能,默认未开启。详见:https://py-free-threading.github.io/
    • 如果想启用该功能,用户需要自己从源代码构建 CPython 解释器,添加 --disable-gil 选项。可执行 python -c "import sys; print(sys._is_gil_enabled())" 来检查 GIL 是否启用。
    • 如果某个 Python 模块调用了 C/C++ 代码,则必须显示声明 GIL_NOT_USED ,否则 Python 解释器依然会启用 GIL 全局锁。
  • 允许在 CPython 解释器中,启用 JIT 即时编译器,从而加快某些 Python 代码的执行速度。
    • 这是一个实验性功能,默认未开启。
    • 如果想启用该功能,用户需要自己从源代码构建 CPython 解释器,添加 --enable-experimental-jit 选项。
到此这篇Python各版本的差异总结_python各版本之间的区别的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 揭开数据可视化的神秘面纱:《Python数据可视化:科技图表绘制》深度解析_揭开数据可视化的神秘面纱:《Python数据可视化:科技图表绘制》深度解析2024-10-30 17:41:37
  • Python赋能AI数据分析开启人工智能新时代_python ai训练2024-10-30 17:41:37
  • 最新Python安装详细教程_python安装教程(2020最新)2024-10-30 17:41:37
  • VS Code配置使用 Python,超详细配置指南,看这一篇就够了_在vscode中配置python2024-10-30 17:41:37
  • AI时代Python大数据分析_大数据分析工具python2024-10-30 17:41:37
  • 安装conda搭建python环境(保姆级教程)_conda安装python2.72024-10-30 17:41:37
  • Python 数据科学手册_Python数据科学手册pdf2024-10-30 17:41:37
  • Leo赠书活动-11期 【利用Python进行数据分析】文末送书_python数据分析 推荐书2024-10-30 17:41:37
  • 这18张 Python 数据科学速查表,让你的代码能力飞起来_21张python速查表2024-10-30 17:41:37
  • 数据分析资料学习《利用Python进行数据分析第2版》+《Python数据科学手册》+《Python数据分析与挖掘实战》代码等_数据分析资料学习《利用Python进行数据分析第2版》+《Python数据科学手册》+《Python数据分析与挖掘实战》代码等2024-10-30 17:41:37
  • 全屏图片