还在撸Python3.7,Python3.9新鲜出炉,菜鸟哥带你尝鲜解读

本文介绍了Python3.9的一些主要更新,包括import异常处理的改进,__file__路径的变化,ast、asyncio、threading、pprint等模块的调整,以及Build和C API的更新,方法的调整和一些模块的移除。例如,Python3.9的ast模块输出更友好,asyncio和pprint功能增强,math.factorial()弃用非整数参数,以及collection.abc抽象基类、sys.getcheckinterval()等的移除。


是不是感觉python3.7刚刚使用,3.8还没捂热乎,怎么3.9这么快就来了! 其实版本迭代速度快,说明这门编程语言的活力强,对于我们使用者来说是件好事,而且谁也没说必须使用最新版本,我到现在仍然在用python3.6。 但是呢,新版本出来了一定要体验一下,看看都有哪些改动和优化,说不定哪个新特性就能解决你手里的大问题。

1

新的特性

1).import异常

我们在进行模块的相对引用时,可能会遇到这个错误提示:ValueError: Attempted relative import beyond toplevel package。简单来说这个问题是由于引用的模块超出了顶层目录的层级结构所导致的,这个问题不理解也没关系,因为跟python3.9的特性更改关系不大。

我们只要知道,python3.9中对这类错误的raise类型进行了调整,当遇到这类错误的时候,会提示ImportError而不再是ValueError,PR如图所示:

这个改动的最大好处就是当遇到这类问题时,系统会明确告诉你是由import模块引发的。

2).__file__路径

我们知道,在python中可以使用__file__、sys.argv[0]、sys.path[0]等方法获取当前脚本的所在路径,只不过在命令行模式下使用前两个命令获取到的都是相对路径,只有第三个命令可以获取脚本的绝对路径。 我们用以前版本的的python运行下面这段代码:
import sys
print(__file__)
print(sys.argv[0])
print(sys.path[0])

得到结果如下:

而如果使用python3.9来运行结果就不一样了(下图),他对__file__和sys.argv[0]都做了调整,使其返回值全部为绝对路径。

3).replace修复

replace是字符串处理中的常用函数,他的原型其实是这样的:

str.replace(old, new[, max])
其中max是可选参数,意思是替换不超过max次。 但是在之前的python版本中,如果对空值进行这种形式的替换会有一点问题,例如下面这段代码,它的输出结果仍然为空。
s = ''
s = s.replace('', 'python39', 1)
print(s)
而在python3.9中对这一问题进行了修正,除非max赋值为0,否则会进行正常的替换操作。 这一改动对bytes和bytearray对象同样适用。


2

模块改动

Python3.9并没有为我们带来新的内置模块,但是对一些模块进行了修改,我们挑选几个使用相对较多的进行说明。

1).ast

ast这个概念大家可能比较陌生,一般来说我们很少有机会用到它,我们只需要知道ast对象是类似一种树形的语法结构。 来看下面这段代码,他的作用就是把print(3+5)转换成ast对象并打印。
import ast
func_def = 'print(3+5)'
r_node = ast.parse(func_def)
print(ast.dump(r_node))

先使用之前的版本来运行,看看下图中的输出结果。我们不用看内容,单从输出格式而言,这串代码既没有换行也没有缩进,看起来很费劲。

而python3.9则对这一问题进行了解决,它在dump()方法中新增了一个参数 indent,代表的是首行缩进的字符长度,我们对上述代码进行少许修改:
import ast
func_def = 'print(3+5)'
r_node = ast.parse(func_def)
print(ast.dump(r_node, indent=2))

然后用python3.9来运行,结果如下,这次看起来是不是舒服多了。

2).asyncio

在python3.9中,新增了一个名为shutdown_default_executor()的协程,它的作用就是等待ThreadPoolExecutor中的所有线程执行完毕,为默认线程安排关闭时间。
需要注意的是,调用此方法后,如果在默认线程中调用loop.run_in_executor()方法,将会引发RuntimeError。

此外,如果我们使用了asyncio.run()类的方法,那么shutdown_default_executor()将会自动调度。也就是说,对于asyncio的一般使用者来说,python3.9的改变并不会带来什么实质性影响。

3).threading

我们知道,在python的子解释器中是不支持守护线程的,在之前的版本中,如果一个线程是从子解释器中调用的守护线程,那么将会导致python程序的崩溃。
在python3.9中,遇到这种情况会引发RuntimeError,这相当于对整个程序加了一层保护。

4).pprint

Python3.9对pprint的修改主要体现在增加了对types.SimpleNamespace的支持。types.SimpleNamespace严格来说是一个简单的对象子类,为了便于理解我们可以简单地把他看作一个数据结构。
下面我就来看看在之前的版本和python3.9中,对types.SimpleNamespace的数据进行pprint结果有什么不同,先来看一段代码:
import pprint
from types import SimpleNamespace
K = [str(i) for i in range(10)]
L = [str(i)*20 for i in range(10)]
D = dict(zip(K, L))
sn = SimpleNamespace(**D)
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(sn)
其中变量sn返回的是一个命名空间,其结构类似于一个dict字典,来看用之前版本的python运行脚本的输出结果:

再来看python3.9中使用pprint的输出结果(下图),这下知道区别在哪了吧。

此外,python3.9中还对其他几个模块进行了修改,例如venv、os等,不过有些改动只针对特定操作系统(比如linux),这里不再一一罗列了。

3

其他优化

除了上面提到的一些改动,python3.9还对一些比较底层的东西进行了优化,这部分内容我想大多数python使用者都涉及不到,大家了解下就好。

1).Build和C API

  • 提供Py_EnterRecursiveCall()和Py_LeaveRecursiveCall()作为limited API的常规函数。 从stable API中删除_Py_CheckRecursionLimit。
  • 向C API添加一个新的公共函数PyObject_CallNoArgs(),这个函数可以调用不含参数的可调用Python对象。
  • 全局变量PyStructSequence_UnnamedField在python3.9中修改为常量字符串。
  • 从Py_LIMITED_API.pyfpe.h中剔除PyFPE_START_PROTECT()和PyFPE_END_PROTECT()函数。
  • 删除PyMethod_ClearFreeList()和PyCFunction_ClearFreeList()函数。

2).方法调整

  • 在之前的版本中,math.factorial()函数只接受非负整数值,否则将引发ValueError。 在python3.9中该函数将弃用,任何参数都将引发TypeError。
  • 弃用parser模块,并将在以后的Python版本中删除。
  • 修改random模块的seeds类型,今后只支持None,int,float,str,bytes和bytearray类型。
  • 始终允许打开GzipFile文件进行读写,即使不指定mode参数也不会发出警告。
  • 推荐使用_tkinter.TkappType的splitlist()方法代替split()方法。

3).移除模块

  • collection.abc 里面的抽象基类将不在常规的 collection 模块中公开。
  • 删除 sys.getcheckinterval() 和 sys.setcheckinterval() 函数。
  • 删除threading.Thread 的 isAlive() 方法。
  • 删除 ElementTree 中的getchildren() 和 getiterator()方法。
  • 删除 旧 plistlib 模块的实现,同时删除其中的use_builtin_types 参数。

小结:
总的来说,目前python3.9相对于3.8改变并不是很大,而且大多数都是一些偏底层的东西,我们一般用户很少会碰到 。 不过,目前推出的python3.9.0a1只是第一个迭代版本,并不是正式版本。后续也有可能会有其他变动,但是按理说变化也不会太大。 基于以上原因,个人认为大家可以继续使用现有的版本学习和工作,如果你现在的版本不算很老的话。
下面做一个调查,看看大家都在用什么版本:

更多有趣有用文章

懒人专用的奇淫技巧,用Python实现炫酷的语音操作电脑
Python里三个最高逼格的调试神器
九大神招,让Python里数据分析神器Jupyter,完美升华
推荐一款Python编辑器,集Pycharm和Sublime优点于一身的王者

老司机吐槽

建议看一下,零基础学Python都想问的6个问题,老司机给你两千字解答
51个Python鲜为人知的秘密特性,老司机看完都惊叹不已
<think> 我们被要求回答关于Python 3.73.9版本区别的问题,并在最后提出3-5个相关问题。 首先,总结两个版本的主要区别Python 3.93.7的后续版本,因此会有一些新特性、优化以及弃用移除的内容。 主要区别包括: 1. 新特性: - 3.9引入了字典合并与更新运算符(||=) - 类型提示的改进(如:`list` 可以直接作为类型注解,而不必从`typing`导入List) - 新的字符串方法(`removeprefix``removesuffix`) - 新的解析器(PEG解析器,为未来的语法特性做准备) 2. 标准库的变化: - 新增模块如`zoneinfo`(时区支持)`graphlib`(拓扑排序) - 一些模块被改进或弃用 3. 性能优化: - 3.9在多个方面进行了性能提升,例如内置函数操作的速度提升 4. 其他变化: - 取消了一些已弃用的功能特性 - 语法上的小改动(例如,在函数参数中允许使用`*``**`的更一般化位置) 注意:虽然有一些新特性,但大多数3.7的代码在3.9上应该可以运行。但是,如果使用了被弃用的特性,则可能需要修改。 接下来,按照格式要求,在回答后提出3-5个相关问题,并以“§§相关问题§§”开头。 我们给出4个相关问题: 1. Python 3.9中引入的字典合并运算符如何使用? 2.Python 3.7迁移到3.9需要注意哪些兼容性问题? 3. 为什么Python 3.9要引入PEG解析器,它有什么优势? 4. 在性能方面,Python 3.9相比3.7有哪些提升? 注意:问题应与主题相关,且基于我们的回答。 </think>### Python 3.73.9 的主要区别 Python 3.7 3.9 都是重要的版本迭代,核心语法兼容但存在显著差异: #### 1. **新特性与语法增强** - **3.9 新增字典合并运算符** `|` `|=` 实现字典合并(替代 `{**d1, **d2}`): ```python d1 = {"a": 1} d2 = {"b": 2} merged = d1 | d2 # {"a":1, "b":2} ``` - **类型标注改进** - 3.9 支持原生类型注解(无需 `typing` 模块): ```python def greet(names: list[str]): ... # 3.9+ ✅ vs 3.7需 List[str] ``` - 新增 `typing.Annotated` 支持元数据注解 #### 2. **标准库更新** - **新模块引入** - `zoneinfo`:内置时区处理(替代第三方库) - `graphlib`:拓扑排序算法 - **字符串处理增强** 3.9 新增字符串方法: ```python "prefix_text".removeprefix("prefix_") # → "text" "text_suffix".removesuffix("_suffix") # → "text" ``` #### 3. **性能优化** - **解析器升级** 3.9 采用 **PEG 解析器**(替代 LL(1)),为未来语法特性铺路(如模式匹配) - **内置操作加速** `str.replace()`, `range` 迭代等操作提速 10-50% #### 4. **弃用与行为变更** - 3.9 移除旧版协议:`collections.abc` 替代 `collections` 部分抽象基类 - 3.9 废弃 `datetime.utcnow()`(改用时区的 `datetime.now(timezone.utc)`) #### 5. **兼容性影响** - **升级建议**:多数 3.7 代码可在 3.9 直接运行 - **注意点**: - C 扩展模块需重新编译 - 使用已弃用API的代码需调整 > **总结**:3.9 在类型系统、语法简洁性、时区处理上提升显著,但无破坏性变更。性能敏感或依赖新特性项目建议升级。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值