关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶、JS/安卓逆向等技术干货!


前言

前几天,也就是 10 月 4 日,Python 发布了 3.10.0 版本,什么?3.9 之后居然不是 4.0?(手动狗头)其实龟叔(Guido van Rossum,吉多·范罗苏姆,Python 之父)早在去年 9 月就说了:

  1. 3.9 之后的版本为 3.10;事实上,它已经存在(在 Github Master 主分支中)。
  2. 如果有版本 4,从 3 到 4 的过渡更像从 1 到 2,而不是从 2 到 3。

相比 Python 3.9,Python 3.10 主要的新功能如下:


PEP 634 - PEP 636:结构模式匹配

在本次诸多的更新中,Structural Pattern Matching 结构模式匹配,match-case 语句无疑是最让人兴奋的功能,也就类似于 Java、C、Go 等其他语言中的 switch-case 语句,具体用法可以参考:PEP 636

来看一个简单的例子:

def http_error(status):match status:case 400:print("Bad request")case 404:print("Not found")case 418:print("I'm a teapot")case _:print("Something's wrong with the internet")http_error(418)  # I'm a teapot
http_error(500)  # Something's wrong with the internet

以上代码中,最后一个 case 中的 _ 并不作为变量名,而表示一种特殊的模式,在前面的 case 中都未命中的情况下,该 case 会是最后的保障,能确保命中,它相当于 Java、C、Go 等语言中的 default 分支:

public class HttpError {public static void main(String args[]){int status = 500;switch(status){case 400:System.out.println("Bad request");case 404:System.out.println("Not found");case 418:System.out.println("I'm a teapot");default:System.out.println("Something's wrong with the internet");}}
}// Something's wrong with the internet

match-case 语法支持可变参数 *args**rest

*args 的用法与 Python 函数中的可变参数是一个用法,允许传入多个参数:

def create_user(command):match command.split():case ["quit"]:quit()case ["create", user]:print("create", user)case ["create", *user]:for u in user:print("create", u)case _:print("command '{command}' not understood")create_user("create user1")
create_user("create user2 user3 user4")# create user1
# create user2
# create user3
# create user4

**rest 会匹配到字典中所有的 keyvalue

def get_dict(dic):match dic:case {**rest}:print("get dict:", rest)case _:print("parameter not understood")get_dict({"400": "Bad request", "404": "Not found", "418": "I'm a teapot"})# get dict: {'400': 'Bad request', '404': 'Not found', '418': "I'm a teapot"}

需要注意的是,结构模式匹配在面对不同的对象时,匹配的规则也有所不同。

当匹配对象是列表(list)或者元组(tuple)的时候,需要长度和元素值都匹配,才能命中:

def create_user(param):match param:case ("quit"):quit()case ("create", user):print("create", user)case ("create", *user):for u in user:print("create", u)case _:print("command '{command}' not understood")create_user(("create", "user1", "user2"))# create user1
# create user2

当匹配对象是一个字典(dict)的时候,只要 case 表达式中的 键(key)在字典对象中存在即可命中,以下示例中,很可能会认为会执行第二个 case,但实际上执行了第一个 case:

def if_action(dic):match dic:case {"action": action}:print("action: %s, no object" % action)case {"action": action, "object": _}:print("action: %s, have object" % action)if_action({"action": "create", "object": "user1"})# action: create, no object

当匹配对象是类对象(class)的时候,匹配的规则和字典(dict)类似,只要对象类型和对象的属性满足条件即可命中,以下示例中,很可能会认为会执行第二个 case,但实际上执行了第一个 case:

class Info:def __init__(self, name, age):self.name, self.age = name, agedef get_info(people):match people:case Info(name="Bob"):print("case 1")case Info(name="Bob", age="20"):print("case 2")people = Info(name="Bob", age="20")
get_info(people)# case 1

PEP 604:新型联合运算符(Union Types)

Python 是个弱类型语言,但是在 Python 3 中支持了定义传参和返回类型的写法:

def test(a: int) -> int:return a**2

通常一个参数和返回值只能是一个类型,在 C/C++,Java,Go 等静态语言里,不可能返回两种类型,或者传参使用两种类型,但是在 Python 里可以:

def test(a: str or int) -> str or int:return a**2

这里的 or 写法看着非常不舒服,所以在 Python 3.5 的时候引入了 typing 模块,推荐使用 Uinon 的写法:

from typing import Uniondef test(a: Union[str, int]) -> Union[str, int]:return a**2

在本次 Python 3.10.0 更新中,PEP 604 允许将联合类型(Union Types)写为 X | Y:

def test(a: str | int) -> str | int:return a**2

新的运算符也可以用作 isinstance()issubclass() 的第二个参数:

print(isinstance(5, int | str))       # True
print(isinstance(None, int | None))   # True
print(issubclass(bool, int | float))  # True
print(isinstance(42, None | str))     # False

PEP 626:错误调试精确到行

在 PEP 626 中,报错提示可以精确到具体行,提示更加详细,在以前的版本中,错误消息一般会指向下一行,而不是实际错误所在的位置,现在可以指向错误代码所在的确切位置。

错误代码示例 1:

li = [1, 2, 3

之前版本报错:

  File "D:\python3Project\test.py", line 5^
SyntaxError: unexpected EOF while parsing

Python 3.10 版本报错:

  File "D:\python310Project\test.py", line 4li = [1, 2, 3^
SyntaxError: '[' was never closed

错误代码示例 2:

expected = {"name": "Bob", "age": 20
some_other_code = foo()

之前版本报错:

  File "D:\python3Project\test.py", line 2some_other_code = foo()^
SyntaxError: invalid syntax

Python 3.10 版本报错:

  File "D:\python310Project\test.py", line 1expected = {"name": "Bob", "age": 20^
SyntaxError: '{' was never closed

PEP 618:zip() 可选长度检查

zip() 是 Python 中的内置函数,用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

在以前的版本中,如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,示例如下:

a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
zipped1 = zip(a, b)
zipped2 = zip(a, c)   # 元素个数与最短的列表一致print([z for z in zipped1])  # [(1, 4), (2, 5), (3, 6)]
print([z for z in zipped2])  # [(1, 4), (2, 5), (3, 6)]

在 PEP 618 中,新增了 strict 参数,设置为 True 时,传入 zip() 的两个可迭代项长度必须相等,否则将抛出 ValueError

a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
zipped1 = zip(a, b, strict=True)
zipped2 = zip(a, c, strict=True)print([z for z in zipped1])
print([z for z in zipped2])

报错:

[(1, 4), (2, 5), (3, 6)]
Traceback (most recent call last):File "D:\python310Project\test.py", line 8, in <module>print([z for z in zipped2])File "D:\python310Project\test.py", line 8, in <listcomp>print([z for z in zipped2])
ValueError: zip() argument 2 is longer than argument 1

BPO-12782:允许带括号的上下文管理器

Python 上下文管理器对于打开/关闭文件、处理数据库连接和很多其他事情都非常有用,在 Python 3.10.0 中,它们的语法将有一点高质量的改进,在 BPO-12782 正式允许带括号的上下文管理器,现在可以用一个 with 语句创建多行,示例如下:

with(open("text1.txt", encoding="utf-8") as f1,open("text2.txt", encoding="utf-8") as f2
):print(f1.read(), f2.read())

PEP 613:显式类型别名

PEP 613 使用 TypeAlias 显式标注类型别名,提高可读性。

以前版本,可以看到,x 很容易被搞混:

x = intdef plus_int(a: x, b: x) -> x:return a+b

Python 3.10 中,使用 TypeAlias 表明这是个别名,消除歧义:

from typing import TypeAliasx: TypeAlias = intdef plus_int(a: x, b: x) -> x:return a+b

性能提升

与所有最新版本的 Python 一样,Python 3.10 也带来了一些性能改进。首先是优化 str()bytes()bytearray() 构造函数,它们速度提升了 30% 左右,代码摘自 BOP-41334:

$ ./python -m pyperf timeit -q --compare-to=../cpython-release2/python "str()"
Mean +- std dev: [/home/serhiy/py/cpython-release2/python] 81.9 ns +- 4.5 ns -> [/home/serhiy/py/cpython-release/python] 60.0 ns +- 1.9 ns: 1.36x faster (-27%)$ ./python -m pyperf timeit -q --compare-to=../cpython-release2/python "bytes()"
Mean +- std dev: [/home/serhiy/py/cpython-release2/python] 85.1 ns +- 2.2 ns -> [/home/serhiy/py/cpython-release/python] 60.2 ns +- 2.3 ns: 1.41x faster (-29%)$ ./python -m pyperf timeit -q --compare-to=../cpython-release2/python "bytearray()"
Mean +- std dev: [/home/serhiy/py/cpython-release2/python] 93.5 ns +- 2.1 ns -> [/home/serhiy/py/cpython-release/python] 73.1 ns +- 1.8 ns: 1.28x faster (-22%)

另一个更值得注意的优化(如果你使用类型注释)是,函数参数及其注释不再在运行时(runtime)计算,而是在编译时计算,这使得创建一个带有参数注释的函数的速度提高了大约 2 倍。

除此之外,Python 核心的各个部分还有更多的优化,你可以在 Python bug tracker 的下列问题中找到更多的细节:BPO-41718、BPO-42927、BPO-43452。


其他改变

  • PEP 623:弃用并准备删除 PyUnicodeObject 中的 wstr 成员。
  • PEP 612:参数规范变量。
  • PEP 632:弃用 distutils 模块,推荐使用 setuptools。
  • PEP 644:CPython 的标准库仅支持 OpenSSL 1.1.1 或更新版本。
  • PEP 624:删除 Py_UNICODE 编码器 API。
  • PEP 597:添加可选的 EncodingWarning。

Python 3.10 正式发布,新增模式匹配,同事用了直呼真香相关推荐

  1. 刚刚,Python 3.10 正式发布了,我发现了一个可怕的功能..

    就在( 2021年10月4日) Python 终于正式发布了 3.10 版本,看了下这个版本的一些特性,最受关注的应该就是 结构模式匹配 了吧?也就是大家所熟悉的 switch-case ,写错了不好 ...

  2. 【Python】刚刚,Python 3.10 正式发布了!我发现了一个可怕的功能...

    就在2021年10月4日, Python 终于正式发布了 3.10 版本,看了下这个版本的一些特性,最受关注的应该就是 结构模式匹配 了吧?也就是大家所熟悉的switch-case,写错了不好意思,是 ...

  3. 刚刚,Python 3.10 正式发布了!我发现了一个可怕的功能...

    " 阅读本文大概需要 8 分钟. " 就在前几天( 2021年10月4日) Python 终于正式发布了 3.10 版本,看了下这个版本的一些特性,最受关注的应该就是 结构模式匹配 ...

  4. python如何对excel批量加密_Python批量处理Excel,真香(超实用!)

    本文介绍了利用Python批量处理Excel文件的一种方法,超实用,超简单.轻松可实现,节省时间不只一点点.文章不长,功能超强. 上菜. 某一天,老板丢个我一个任务.需要将400多张表按照一定条件进行 ...

  5. java 拼接html_程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

    1.曾经不止一次在生产中见过类似这样的代码: 这有很多变种,例如用 Integer.valueOf(1). (Integer)1 之类的,那些细节都不重要.重要的是:凭空用一个 Integer 对象作 ...

  6. java 代码 _程序员用1.5小时写出的Java代码,让同事瞠目结舌!直呼优秀

    1.曾经不止一次在生产中见过类似这样的代码: 这有很多变种,例如用 Integer.valueOf(1). (Integer)1 之类的,那些细节都不重要.重要的是:凭空用一个 Integer 对象作 ...

  7. 吊打 CLIP 平均10个点,Meta 多模态通用模型 FLAVA真香啊

    厉害了!作者将单一模型运用于三个不同领域的不同任务,结构简单且训练直观,还能有着出色的表现. 自Transformer横空出世,从NLP到CV,再到今天的多模态,无数基于Transformer的模型被 ...

  8. 10分钟弄懂微应用框架——乾坤,真香!

    前言 今天刚刚学习了一个微前端框架--乾坤,正着热乎劲,写一篇入门博客.这篇文章不会讨论太多的原理和实现,只是一个入门写 Hello World 的教程. 文章的很多地方都参考官网,但是官网的教程太简 ...

  9. 真香!端午节到来,我用Python画了几个粽子送给女票,女票差点吃了我的电脑...

    前言 小伙伴们好,我是二哥(二师兄),端午节就要到了,提前祝各位假期愉快,端午安康! 二哥突发奇想,用Python画了几个粽子送给女友,由于色香味俱全,没想到她差点把我的电脑吃了,跪地直呼真香! 喜欢 ...

最新文章

  1. Codemirror-开源在线代码编辑器
  2. Maven 的 settings.xml 配置中的mirror节点
  3. Makefile 学习 2 - 基于若干 Blog 的汇总
  4. C++基础 (1) 常见的易错问题
  5. Redis分布式缓存
  6. 牛客网 在线编程 局部最小值位置
  7. phpcms 轮播图 (posid推荐位 )调用 - 代码篇
  8. 【JAVA 第五章 】课后习题 奇数排前
  9. 第一个冲刺周期第二天补发
  10. 昆明职高计算机学校,昆明职高学校,昆明职高学校前十强,昆明职高学校哪些比较好一点 - IT教育频道...
  11. Windows7 的激活命令小结
  12. python实现高级计算器_Python实现的复杂的计算器的代码
  13. 计算与推断思维 五、表格
  14. 我的世界服务器ess汉化文件,《我的世界》ess插件指令大全
  15. WWDC20 苹果发布会
  16. 中学计算机教师守则,[最新]中学“教师计算机使用管理制度”
  17. 使用Scanner收集你的身高体重,并计算出你的BMI值是多少 BMI的计算公式是 体重(kg) / (身高*身高)
  18. IE浏览器不能上网而其他浏览器可以正常上网解决办法
  19. Java入门篇——安装Java SE14
  20. arcgis for js通过框架配置实现点线面及echarts绘制

热门文章

  1. js/css文件修改后浏览器本地缓存解决
  2. [hackinglab][CTF][上传关][2020] hackinglab 上传关 writeup
  3. 【数据结构与算法】【算法思想】【推荐系统】向量空间
  4. [Leedcode][JAVA][第470题][Ran7()实现Rand10()]
  5. linux日志服务器配置在哪个文件,Linux中日志的基本配置(syslog)
  6. bow 折叠键盘 linux,bow便携折叠蓝牙键盘体验
  7. 宾馆管理系统mysql_宾馆管理系统(含源码和数据库文件)
  8. 什么是ie浏览器_?IE 浏览器为什么不招人待见?
  9. 红石32位cpu通用计算机,我的世界无命令方块32位红石电脑装置详解
  10. table 表格点击当前行按钮隐藏当前的另一个按钮_Excel表格为什么那么慢已经应该如何解决(四)一类特殊的函数易变函数(volatile function)...