快速學會使用Python3.12的新特性

一、 PEP 695: 類型形參語法的革新

PEP 695 在 Python 3.12 中引入了一種新穎且更為清晰的方式來定義泛型類和函數,旨在提升類型參數的明確性和簡潔性。這個提案不僅改善了類型系統的可讀性,還增強了其功能性。以下是這些變化的詳細概述:

1. 泛型類和函數的新定義方式

在 PEP 484 的基礎上,PEP 695 引入了一種更緊湊、明確的泛型類和函數的創建方法。與以前的詳細語法相比,新方法更簡潔,且類型參數的范圍更加明確。例如:

def max[T](args: Iterable[T]) -> T:...class list[T]:def __getitem__(self, index: int, /) -> T:...def append(self, element: T) -> None:...
2. 類型別名的新聲明方式

PEP 695 還引入了使用 type 語句聲明類型別名的方法。這些別名可以是普通類型或泛型類型,為類型注解提供了更多的靈活性。例如:

type Point = tuple[float, float]
type Point[T] = tuple[T, T]
3. 新的類型參數聲明

這個提案允許聲明各種新的類型參數,例如 TypeVarTupleParamSpec,以及帶邊界或約束的 TypeVar。這些新的類型參數擴展了 Python 類型系統的表達能力。例如:

type IntFunc[**P] = Callable[P, int]  # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts]  # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T]  # TypeVar with bound
type IntOrStrSequence[T: (int, str)] = Sequence[T]  # TypeVar with constraints
4. 惰性求值和作用域

PEP 695 強調,類型別名的值和類型變量的邊界、約束僅在需要時進行求值,即實現了惰性求值。這意味著類型別名可以引用稍后在文件中定義的其他類型。同時,通過類型參數列表聲明的類型參數在其聲明的作用域內及嵌套作用域內可見,但在外部作用域不可見。

5. 標注作用域的引入

為了支持這些作用域定義,PEP 695 引入了一種新的作用域——標注作用域。這種作用域在很大程度上類似于函數作用域,但其與封閉類作用域的交互方式有所不同。在未來的 Python 3.13 中,標注也將在這種新的標注作用域中進行求值。

通過這些改進,PEP 695 不僅提高了類型注解的可讀性和易用性,還為 Python 類型系統帶來了更強的表達力和靈活性。更多細節可以在 PEP 695 中找到。

二、 PEP 701: 對 f-字符串的增強和放寬限制

Python 3.12 中的 PEP 701 帶來了對 f-字符串(格式化字符串)的顯著改進,放寬了之前的一些限制,使其更加強大和靈活。以下是這些改進的詳細介紹:

1. 引號的重用

在 Python 3.11 及之前版本中,f-字符串中不能使用與其本身相同的引號,否則會引發 SyntaxError。例如,如果 f-字符串用單引號標記,則表達式部分不能包含單引號。這種限制在 Python 3.12 中被取消,現在你可以在 f-字符串的表達式部分自由使用任何類型的引號。例如:

songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
f"This is the playlist: {', '.join(songs)}"
# 輸出: 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'

此外,這項改變使得 f-字符串可以更靈活地嵌套使用,如:

f"{f'{f"{f"{f"{1+1}"}"}"}'}"
# 輸出: '2'
2. 多行表達式和注釋

在以前的版本中,f-字符串的表達式必須在一行內完成,這對于復雜的表達式或需要注釋的情況不太方便。Python 3.12 允許 f-字符串表達式跨越多行,并支持在其中添加注釋,使代碼更易于理解和維護。例如:

f"""This is the playlist: {', '.join(['Take me back to Eden',  # My, my, those eyes like fire'Alkaline',              # Not acid nor alkaline'Ascensionism'           # Take to the broken skies at last
])}"""
# 輸出: 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'
3. 反斜杠和 Unicode 字符

在 Python 3.12 之前,f-字符串表達式中不能包含任何反斜杠 (\) 字符,這限制了 Unicode 轉義序列的使用。現在,你可以在 f-字符串表達式中使用反斜杠和 Unicode 轉義序列。例如:

songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
print(f"This is the playlist: {'\n'.join(songs)}")
# 輸出: 
# This is the playlist: Take me back to Eden
# Alkaline
# Ascensionismprint(f"This is the playlist: {'\N{BLACK HEART SUIT}'.join(songs)}")
# 輸出: 'This is the playlist: Take me back to Eden?Alkaline?Ascensionism'

總的來說,PEP 701 為 Python 開發者提供了更大的靈活性和表達能力,尤其是在處理復雜的字符串格式化時。這些改進使得 f-字符串成為一個更加強大和便捷的工具。

4. f-字符串錯誤消息的變化

在 Python 3.11 及以前版本中,f-字符串的錯誤消息往往缺乏精確性。例如,在遇到語法錯誤時,Python 3.11 可能會給出如下錯誤提示:

my_string = f"{x z y}" + f"{1 + 1}"
# 錯誤輸出:
#   File "<stdin>", line 1
#     (x z y)
#      ^^^
# SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

在這種情況下,錯誤消息不僅沒有準確指出錯誤的具體位置,而且錯誤的表達式被不自然地用括號括起來。

Python 3.12 使用 PEG 解析器來解析 f-字符串,使得錯誤消息變得更加精確和有用。現在,當遇到類似的語法錯誤時,錯誤消息會精確指出錯誤所在的位置,并顯示整行代碼:

my_string = f"{x z y}" + f"{1 + 1}"
# 錯誤輸出:
#   File "<stdin>", line 1
#     my_string = f"{x z y}" + f"{1 + 1}"
#                    ^^^
# SyntaxError: invalid syntax. Perhaps you forgot a comma?

四、PEP 684: 引入解釋器級 GIL 提高 Python 多核性能

PEP 684 在 Python 3.12 中引入了一個重要的更新——解釋器級的全局解釋器鎖(GIL)。這項改進旨在解決 Python 在多核 CPU 性能方面的一些限制,為 Python 帶來更好的并行計算能力。

1. 解釋器級 GIL 的概念

GIL 是 Python 解釋器中一個眾所周知的特性,它在任何時候只允許一個線程執行 Python 字節碼。雖然這簡化了 CPython 解釋器的設計并提高了單線程程序的性能,但它也限制了 Python 程序在多核處理器上的并行執行能力。

PEP 684 通過引入解釋器級 GIL,使得可以創建帶有獨立 GIL 的子解釋器。這意味著每個子解釋器可以在其自己的線程中獨立運行,從而更好地利用多核 CPU 的性能。

2. 如何創建帶有獨立 GIL 的解釋器

目前,這個特性只能通過 C-API 實現,預計在 Python 3.13 中將添加相應的 Python API。使用 Py_NewInterpreterFromConfig() 函數可以創建一個具有獨立 GIL 的新解釋器。以下是一個示例代碼:

PyInterpreterConfig config = {.check_multi_interp_extensions = 1,.gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {return -1;
}
// 新解釋器現在在當前線程中激活
3. 示例和進一步的應用

更多關于如何使用 C-API 來操作子解釋器和解釋器級 GIL 的示例可以在 Modules/_xxsubinterpretersmodule.c 中找到。

總體而言,PEP 684 的引入為 Python 的并行處理和多核性能優化提供了一個重要的步驟,使 Python 在多核處理器上的應用變得更加高效。這一改進由 Eric Snow 貢獻,并在 gh-104210 等項目中得以實現。

五、 PEP 669: 為 CPython 引入低影響監控機制

PEP 669 在 Python 3.12 中引入了一個為 CPython 設計的新 API,用于實現低影響的性能監控。這一提案的核心在于為性能分析器、調試器和其他監控工具提供了一個高效且對程序性能影響小的監控方式。

1.新 API 的特點和優勢
  1. 廣泛的事件覆蓋:該 API 能監控包括函數調用、返回、代碼行執行、異常處理和跳轉等在內的多種事件,為開發者提供全面的性能分析視角。

  2. 精確的性能開銷控制:PEP 669 允許開發者只對他們需要監控的事件付出性能開銷。這種選擇性監控大大降低了對程序性能的影響,尤其是在生產環境中。

  3. 近零開銷的調試和覆蓋工具支持:通過這個 API,開發者可以使用幾乎不影響程序性能的調試器和代碼覆蓋工具,這在以往的 Python 版本中是難以實現的。

2. 使用 sys.monitoring 模塊

這個新引入的 sys.monitoring 模塊提供了訪問和控制事件監控的接口。通過這個模塊,開發者可以注冊監控事件、控制監控的粒度和范圍,以及收集和分析性能數據。具體使用方法和 API 文檔可以在 sys.monitoring 中找到。

六、 PEP 688: 在 Python 中使緩沖區協議更易于訪問

PEP 688 為 Python 3.12 帶來了對緩沖區協議的重要改進,使得在 Python 代碼中使用和實現緩沖區協議變得更加直接和易于管理。

1. 緩沖區協議的 Python 實現

緩沖區協議(buffer protocol)在 Python 中主要用于提供一種訪問對象內存表示的機制。這個協議常見于需要高性能數據處理的場景,比如在處理大量數據或進行科學計算時。

PEP 688 引入了以下關鍵特性:

  1. __buffer__() 方法: 類通過實現 __buffer__() 方法可以作為緩沖區類型使用。這允許自定義類直接支持緩沖區協議,從而與 Python 的內置緩沖區類型(如字節串和數組)一樣,可以更有效地處理數據。

  2. collections.abc.Buffer 抽象基類: 這個新引入的抽象基類定義了緩沖區對象應有的基本行為和接口。通過實現這個類,開發者可以確保他們的自定義緩沖區類型符合預期的標準,從而提高代碼的可維護性和可讀性。

  3. inspect.BufferFlags 枚舉: 這個新的枚舉提供了一組標志,用于自定義緩沖區的創建過程。這些標志讓開發者能夠更精確地控制緩沖區的行為,如只讀或只寫訪問,以及緩沖區的其他屬性。

2. 應用和好處

這些改進使得緩沖區協議在 Python 中更易于訪問和使用,特別是對于需要高效數據處理的應用。它們還提高了與緩沖區相關的代碼的可讀性和可維護性,使得開發者能夠更容易地實現和使用復雜的內存管理邏輯。這對于科學計算、數據分析、圖像處理等領域的 Python 開發者來說,是一個重要的步驟。

七、 Python 3.12 更新:改進的錯誤消息和類型提示特性

Python 3.12 版本中包含了對錯誤消息和類型提示的重要改進,這些更新旨在提高代碼的可讀性和易用性。

1. 改進的錯誤消息
  1. 更明確的 NameError 提示:

    • 當引發 NameError 并傳播到最高層級時,如果與標準庫中的模塊名稱相關,錯誤消息會建議可能的導入。
    • 示例:
      >>> sys.version_info
      NameError: name 'sys' is not defined. Did you forget to import 'sys'?
      
  2. 針對實例的 NameError 改進:

    • 如果在類方法中出現 NameError,且實例具有與異常中名稱相同的屬性,則錯誤建議會包括 self.<NAME>
    • 示例:
      class A:def __init__(self):self.blech = 1def foo(self):somethin = blechA().foo()
      # NameError: name 'blech' is not defined. Did you mean: 'self.blech'?
      
  3. 改進的 SyntaxError:

    • 當用戶錯誤地使用 import x from y 語法時,會提示正確的 from y import x 形式。
    • 示例:
      >>> import a.y.z from b.y.z
      SyntaxError: Did you mean to use 'from ... import ...' instead?
      
  4. 更有幫助的 ImportError:

    • 如果嘗試從模塊導入不存在的名稱時,將會根據模塊中的可用名稱提出建議。
    • 示例:
      >>> from collections import chainmap
      ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?
      
2. 類型的新增特性
  1. PEP 692: TypedDict 的應用:

    • 允許使用 TypedDict 來更精確地注釋 **kwargs
    • 示例:
      from typing import TypedDict, Unpackclass Movie(TypedDict):name: stryear: intdef foo(**kwargs: Unpack[Movie]):...
      
  2. PEP 698: typing.override 裝飾器:

    • 這個新裝飾器指示方法旨在重寫超類中的方法,幫助捕獲錯誤。
    • 示例:
      from typing import overrideclass Base:def get_color(self) -> str:return "blue"class GoodChild(Base):@overridedef get_color(self) -> str:return "yellow"class BadChild(Base):@overridedef get_colour(self) -> str:return "red"
      # 'BadChild.get_colour' 引發類型檢查器錯誤,因為它沒有重寫 'Base.get_color'
      

這些改進不僅提升了 Python 的錯誤消息的準確性和可理解性,還增強了類型提示的表達能力,使得 Python 代碼更加健壯和易于維護。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164519.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164519.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164519.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(四)C語言之符號常量概述

&#xff08;四&#xff09;C語言之符號常量概述 一、符號常量概述 一、符號常量概述 在程序中使用像300,20等這樣的等類似的“幻數”不是一個好的習慣&#xff0c;它們無法向閱讀該程序的人提供更多有用的信息&#xff0c;從而使得修改程序變得困難。處理這種幻數的一種方法是…

unreal 指定windows SDK

路徑 &#xff1a; “C:\Users\Administrator\AppData\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml” 在Configuration中添加 <WindowsPlatform><WindowsSdkVersion>10.0.20348.0</WindowsSdkVersion></WindowsPlatform>示例&…

R數據分析:集成學習方法之隨機生存森林的原理和做法,實例解析

很久很久以前給大家寫過決策樹&#xff0c;非常簡單明了的算法。今天給大家寫隨機&#xff08;生存&#xff09;森林&#xff0c;隨機森林是集成了很多個決策數的集成模型。像隨機森林這樣將很多個基本學習器集合起來形成一個更加強大的學習器的這么一種集成思想還是非常好的。…

算法面試題:反轉一個整數

題目&#xff1a;反轉一個整數。例如&#xff0c;輸入123&#xff0c;輸出321&#xff1b;輸入-456&#xff0c;輸出-654。注意&#xff1a;反轉后的整數在32位帶符號整數范圍內。 編寫一個函數 reverseInteger(x: int) -> int 來實現這個功能。 答案&#xff1a; def re…

【前端】必學知識ES6 1小時學會

1.ES6概述 2.let和const的認識 3.let、const、var的區別 4.模板字符串 5.函數默認參數 6.箭頭函數【重點】 ?編輯7.對象初始化簡寫以及案例分析 【重點】 8.對象解構 8.對象傳播操作符 9.對象傳播操作符案例分析 ?編輯 10.數組Map 11.數組Reduce 12.NodeJS小結 …

代碼隨想錄算法訓練營第四十四天【動態規劃part06】 | 完全背包、518. 零錢兌換 II、377. 組合總和 Ⅳ

完全背包 有N件物品和一個最多能背重量為W的背包。第i件物品的重量是weight[i]&#xff0c;得到的價值是value[i] 。每件物品都有無限個&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解將哪些物品裝入背包里物品價值總和最大。 題目鏈接&#xff1a; 題目頁…

計算機畢業設計 基于Hadoop的物品租賃系統的設計與實現 Java實戰項目 附源碼+文檔+視頻講解

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精…

YOLO目標檢測——泄露檢測數據集下載分享【含對應voc、coco和yolo三種格式標簽】

實際項目應用&#xff1a;泄露檢測數據集說明&#xff1a;泄露檢測數據集&#xff0c;真實場景的高質量圖片數據&#xff0c;數據場景豐富&#xff0c;含多個類別標簽說明&#xff1a;使用lableimg標注軟件標注&#xff0c;標注框質量高&#xff0c;含voc(xml)、coco(json)和yo…

AES 加解密

AES 加解密 AES(Advanced Encryption Standard),又稱高級加密標準,是一種對稱加密算法,也是目前廣泛使用的加密技術之一。其主要特點是加密速度快、安全性高、可擴展性好等。 AES 算法采用對稱加密的方式,即加密和解密使用相同的密鑰進行操作。密鑰長度可以是 128、192…

【JavaSE】不允許你不會使用String類

&#x1f3a5; 個人主頁&#xff1a;深魚~&#x1f525;收錄專欄&#xff1a;JavaSE&#x1f304;歡迎 &#x1f44d;點贊?評論?收藏 目錄 前言&#xff1a; 一、常用方法 1.1 字符串構造 1.2 String對象的比較 &#xff08;1&#xff09;比較是否引用同一個對象 注意…

從零開始的C++(十九)

紅黑樹&#xff1a; 一種接近平衡的二叉樹&#xff0c;平衡程度低于搜索二叉樹。 特點&#xff1a; 1.根節點為黑 2.黑色結點的子結點可以是紅色結點或黑色結點。 3.紅色結點的子結點只能是黑色結點。 4.每個結點到其所有葉子結點的路徑的黑色結點個數相同。 5.指向空的…

OmniGraffle

安裝 在mac上安裝OmniGraffle&#xff0c;找一個正版或者啥的都行&#xff0c;安裝好后&#xff0c;可以直接在網上找一個激活碼&#xff0c;然后找到軟件的許可證&#xff0c;進行添加即可。 使用 新建空白頁 然后圖形啥的看一眼工具欄就知道了&#xff0c;顏色形狀還是挺…

音視頻項目—基于FFmpeg和SDL的音視頻播放器解析(二十一)

介紹 在本系列&#xff0c;我打算花大篇幅講解我的 gitee 項目音視頻播放器&#xff0c;在這個項目&#xff0c;您可以學到音視頻解封裝&#xff0c;解碼&#xff0c;SDL渲染相關的知識。您對源代碼感興趣的話&#xff0c;請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本…

【C++】拷貝構造函數,析構函數詳解!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;個人主頁 &#xff1a;阿然成長日記 …

【LeetCode】挑戰100天 Day13(熱題+面試經典150題)

【LeetCode】挑戰100天 Day13&#xff08;熱題面試經典150題&#xff09; 一、LeetCode介紹二、LeetCode 熱題 HOT 100-152.1 題目2.2 題解 三、面試經典 150 題-153.1 題目3.2 題解 一、LeetCode介紹 LeetCode是一個在線編程網站&#xff0c;提供各種算法和數據結構的題目&…

Vue3 實現elementPlus的table列寬調整和拖拽

1、需要的包 // 除了Vue和element-plus外還需要以下的包 npm install sortablejs2、具體代碼如下&#xff0c;可直接粘貼運行 <template><div class"draggable-table"><el-table ref"tableRef":data"tableData.data":key"…

Java-飛翔的小鳥

前言 基于Java的飛翔小鳥游戲&#xff0c;本代碼來自b站up主分享。本游戲所需的圖片素材需要自己獲取并下載&#xff0c;在此視頻下&#xff0c;視頻鏈接&#xff1a;【Java經典小游戲項目之飛翔的小鳥】 https://www.bilibili.com/video/BV1ou411o7br/?p10&share_source…

C#編程題分享(4)

換行輸出整數問題 輸?任意?個位數未知的整數&#xff0c;輸出這個數每?位上的數字。輸出的時候&#xff0c;從個位開始輸出&#xff0c;每輸出?個數字換??。樣例輸?&#xff1a;3547 輸出&#xff1a;7 換行輸出 4 換行輸出5 換行輸出3 int n Convert.ToInt32(Conso…

【python基礎(九)】文件和異常詳解:使用、讀取、寫入、追加、保存用戶的信息,以及優雅的處理異常

文章目錄 一. 從文件中讀取數據1. 讀取整個文件2. 文件路徑3. 逐行讀取4. 創建一個包含文件各行內容的列表 二. 寫入文件1. 寫入空文件2. 寫入多行3. 附加到文件 三. 異常1. 處理ZeroDivisionError異常2. 使用try-except代碼塊3. try-except-else ing4. 處理FileNotFoundError異…

如何在AD上創建完整的項目

首先&#xff0c;我們先安裝好AD&#xff0c;這里我使用的是AD22&#xff0c;安裝過程如下&#xff1a; Altium Designer 22下載安裝教程-CSDN博客 Altium Designer 22是全球領先的PCB設計軟件之一&#xff0c;為電路板設計師提供了一種集成的解決方案&#xff0c;旨在簡化和加…