日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

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

發(fā)布時(shí)間:2023/12/10 python 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 3.10 正式发布,新增模式匹配,同事用了直呼真香 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


關(guān)注微信公眾號(hào):K哥爬蟲(chóng),QQ交流群:808574309,持續(xù)分享爬蟲(chóng)進(jìn)階、JS/安卓逆向等技術(shù)干貨!


前言

前幾天,也就是 10 月 4 日,Python 發(fā)布了 3.10.0 版本,什么?3.9 之后居然不是 4.0?(手動(dòng)狗頭)其實(shí)龜叔(Guido van Rossum,吉多·范羅蘇姆,Python 之父)早在去年 9 月就說(shuō)了:

  • 3.9 之后的版本為 3.10;事實(shí)上,它已經(jīng)存在(在 Github Master 主分支中)。
  • 如果有版本 4,從 3 到 4 的過(guò)渡更像從 1 到 2,而不是從 2 到 3。
  • 相比 Python 3.9,Python 3.10 主要的新功能如下:


    PEP 634 - PEP 636:結(jié)構(gòu)模式匹配

    在本次諸多的更新中,Structural Pattern Matching 結(jié)構(gòu)模式匹配,match-case 語(yǔ)句無(wú)疑是最讓人興奮的功能,也就類(lèi)似于 Java、C、Go 等其他語(yǔ)言中的 switch-case 語(yǔ)句,具體用法可以參考:PEP 636

    來(lái)看一個(gè)簡(jiǎn)單的例子:

    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

    以上代碼中,最后一個(gè) case 中的 _ 并不作為變量名,而表示一種特殊的模式,在前面的 case 中都未命中的情況下,該 case 會(huì)是最后的保障,能確保命中,它相當(dāng)于 Java、C、Go 等語(yǔ)言中的 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 語(yǔ)法支持可變參數(shù) *args 和 **rest。

    *args 的用法與 Python 函數(shù)中的可變參數(shù)是一個(gè)用法,允許傳入多個(gè)參數(shù):

    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 會(huì)匹配到字典中所有的 key 和 value:

    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"}

    需要注意的是,結(jié)構(gòu)模式匹配在面對(duì)不同的對(duì)象時(shí),匹配的規(guī)則也有所不同。

    當(dāng)匹配對(duì)象是列表(list)或者元組(tuple)的時(shí)候,需要長(zhǎng)度和元素值都匹配,才能命中:

    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

    當(dāng)匹配對(duì)象是一個(gè)字典(dict)的時(shí)候,只要 case 表達(dá)式中的 鍵(key)在字典對(duì)象中存在即可命中,以下示例中,很可能會(huì)認(rèn)為會(huì)執(zhí)行第二個(gè) case,但實(shí)際上執(zhí)行了第一個(gè) 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

    當(dāng)匹配對(duì)象是類(lèi)對(duì)象(class)的時(shí)候,匹配的規(guī)則和字典(dict)類(lèi)似,只要對(duì)象類(lèi)型和對(duì)象的屬性滿(mǎn)足條件即可命中,以下示例中,很可能會(huì)認(rèn)為會(huì)執(zhí)行第二個(gè) case,但實(shí)際上執(zhí)行了第一個(gè) 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:新型聯(lián)合運(yùn)算符(Union Types)

    Python 是個(gè)弱類(lèi)型語(yǔ)言,但是在 Python 3 中支持了定義傳參和返回類(lèi)型的寫(xiě)法:

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

    通常一個(gè)參數(shù)和返回值只能是一個(gè)類(lèi)型,在 C/C++,Java,Go 等靜態(tài)語(yǔ)言里,不可能返回兩種類(lèi)型,或者傳參使用兩種類(lèi)型,但是在 Python 里可以:

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

    這里的 or 寫(xiě)法看著非常不舒服,所以在 Python 3.5 的時(shí)候引入了 typing 模塊,推薦使用 Uinon 的寫(xiě)法:

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

    在本次 Python 3.10.0 更新中,PEP 604 允許將聯(lián)合類(lèi)型(Union Types)寫(xiě)為 X | Y:

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

    新的運(yùn)算符也可以用作 isinstance() 和 issubclass() 的第二個(gè)參數(shù):

    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:錯(cuò)誤調(diào)試精確到行

    在 PEP 626 中,報(bào)錯(cuò)提示可以精確到具體行,提示更加詳細(xì),在以前的版本中,錯(cuò)誤消息一般會(huì)指向下一行,而不是實(shí)際錯(cuò)誤所在的位置,現(xiàn)在可以指向錯(cuò)誤代碼所在的確切位置。

    錯(cuò)誤代碼示例 1:

    li = [1, 2, 3

    之前版本報(bào)錯(cuò):

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

    Python 3.10 版本報(bào)錯(cuò):

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

    錯(cuò)誤代碼示例 2:

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

    之前版本報(bào)錯(cuò):

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

    Python 3.10 版本報(bào)錯(cuò):

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

    PEP 618:zip() 可選長(zhǎng)度檢查

    zip() 是 Python 中的內(nèi)置函數(shù),用于將可迭代的對(duì)象作為參數(shù),將對(duì)象中對(duì)應(yīng)的元素打包成一個(gè)個(gè)元組,然后返回由這些元組組成的列表。

    在以前的版本中,如果各個(gè)迭代器的元素個(gè)數(shù)不一致,則返回列表長(zhǎng)度與最短的對(duì)象相同,示例如下:

    a = [1, 2, 3] b = [4, 5, 6] c = [4, 5, 6, 7, 8] zipped1 = zip(a, b) zipped2 = zip(a, c) # 元素個(gè)數(shù)與最短的列表一致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 參數(shù),設(shè)置為 True 時(shí),傳入 zip() 的兩個(gè)可迭代項(xiàng)長(zhǎng)度必須相等,否則將拋出 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])

    報(bào)錯(cuò):

    [(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:允許帶括號(hào)的上下文管理器

    Python 上下文管理器對(duì)于打開(kāi)/關(guān)閉文件、處理數(shù)據(jù)庫(kù)連接和很多其他事情都非常有用,在 Python 3.10.0 中,它們的語(yǔ)法將有一點(diǎn)高質(zhì)量的改進(jìn),在 BPO-12782 正式允許帶括號(hào)的上下文管理器,現(xiàn)在可以用一個(gè) with 語(yǔ)句創(chuàng)建多行,示例如下:

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

    PEP 613:顯式類(lèi)型別名

    PEP 613 使用 TypeAlias 顯式標(biāo)注類(lèi)型別名,提高可讀性。

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

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

    Python 3.10 中,使用 TypeAlias 表明這是個(gè)別名,消除歧義:

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

    性能提升

    與所有最新版本的 Python 一樣,Python 3.10 也帶來(lái)了一些性能改進(jìn)。首先是優(yōu)化 str(),bytes() 和 bytearray() 構(gòu)造函數(shù),它們速度提升了 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%)

    另一個(gè)更值得注意的優(yōu)化(如果你使用類(lèi)型注釋)是,函數(shù)參數(shù)及其注釋不再在運(yùn)行時(shí)(runtime)計(jì)算,而是在編譯時(shí)計(jì)算,這使得創(chuàng)建一個(gè)帶有參數(shù)注釋的函數(shù)的速度提高了大約 2 倍。

    除此之外,Python 核心的各個(gè)部分還有更多的優(yōu)化,你可以在 Python bug tracker 的下列問(wèn)題中找到更多的細(xì)節(jié):BPO-41718、BPO-42927、BPO-43452。


    其他改變

    • PEP 623:棄用并準(zhǔn)備刪除 PyUnicodeObject 中的 wstr 成員。
    • PEP 612:參數(shù)規(guī)范變量。
    • PEP 632:棄用 distutils 模塊,推薦使用 setuptools。
    • PEP 644:CPython 的標(biāo)準(zhǔn)庫(kù)僅支持 OpenSSL 1.1.1 或更新版本。
    • PEP 624:刪除 Py_UNICODE 編碼器 API。
    • PEP 597:添加可選的 EncodingWarning。

    總結(jié)

    以上是生活随笔為你收集整理的Python 3.10 正式发布,新增模式匹配,同事用了直呼真香的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。