Following system colour scheme - Python 增強提案 Selected dark colour scheme - Python 增強提案 Selected light colour scheme - Python 增強提案

Python 增強提案

PEP 423 – 與打包相關的命名約定和方法

作者:
Benoit Bryon <benoit at marmelune.net>
討論至:
Distutils-SIG 郵件列表
狀態:
推遲
型別:
資訊性
主題:
打包
建立日期:
2012年5月24日
釋出歷史:


目錄

摘要

本文件涉及

  • Python專案名稱,
  • 正在分發的Python包或模組名稱,
  • 名稱空間包。

它為分發作者提供了指南和方法

PEP 延期

本PEP的進一步審議已被推遲,至少要等到 PEP 426(軟體包元資料2.0)及相關更新解決之後。

術語

參考是Python文件中的打包術語

與其他 PEP 的關係

  • PEP 8 處理程式碼風格指南,包括Python包和模組的名稱。它涵蓋了包/模組名稱的語法。
  • PEP 345 處理打包元資料,並定義了 packaging.core.setup() 函式的名稱引數。
  • PEP 420 處理名稱空間包。它為Python核心帶來了名稱空間包的支援。在此之前,名稱空間包是由外部庫實現的。
  • PEP 3108 處理應用於標準庫的Python 2.x和Python 3.x之間的過渡:一些模組將被刪除,一些將被重新命名。它指出命名約定很重要,並且是一個過渡計劃的例子。

概述

以下是選擇名稱時應遵循的指南摘要列表

如有疑問,請諮詢

如果您閱讀本文件後仍感到不確定,請在IRC或郵件列表上諮詢Python社群

頂級名稱空間與程式碼所有權相關

這有助於避免專案名稱之間的衝突。

所有權可以是

  • 個人。示例:gp.fileupload 由Gael Pasgrimaud擁有和維護。
  • 組織。示例
    • zest.releaser 由Zest Software擁有和維護。
    • Django 由Django Software Foundation擁有和維護。
  • 一個團體或社群。示例:sphinx 由Sphinx專案的開發人員維護,而不僅僅是其作者Georg Brandl。
  • 與另一個包相關的團體或社群。示例:collective.recaptcha 由其作者David Glick,Groundwire擁有。但“collective”名稱空間由Plone社群擁有。

尊重所有權

在使用名稱空間之前,請了解其目的。

除非明確授權,否則不要插入您不擁有的名稱空間。

如有疑問,請諮詢.

例如,不要插入“django.contrib”名稱空間,因為它由Django的核心貢獻者管理。

專案作者可以定義例外情況。參見下面的組織社群貢獻

此外,此規則適用於非Python專案。

例如,不要使用“apache”作為頂級名稱空間:“Apache”是一個現有專案的名稱(在“Apache”的情況下,它也是一個商標)。

私有(包括閉源)專案使用名稱空間

...因為私有專案由某人擁有。因此,應用所有權規則

對於內部/客戶專案,使用您的公司名稱作為名稱空間。

此規則適用於閉源專案。

例如,如果您正在為“Python Sport”公司建立一個“climbing”專案:使用“pythonsport.climbing”名稱,即使它是閉源的。

個人專案使用名稱空間

...因為它們由個人擁有。因此,應用所有權規則

即使專案具有“內部”或“個人”名稱,將其作為開源專案釋出也無需羞愧。

如果專案發展到作者希望更改所有權的地步(即專案不再屬於個人),請記住重新命名專案很容易

社群擁有的專案可以避免名稱空間包

如果您的專案足夠通用(即它不是另一個產品或框架的貢獻),您可以避免名稱空間包。基本條件通常是您的專案由專門從事此專案的團體(即開發團隊)擁有。

只有當您確實打算讓程式碼為社群所有時,才使用“共享”名稱空間。

例如,sphinx專案屬於Sphinx開發團隊。沒有必要擁有一個只有一個“sphinx.sphinx”專案的“sphinx”名稱空間包。

如有疑問,請使用個人/組織名稱空間

如果您的專案確實是實驗性的,最好的選擇是使用個人或組織名稱空間

  • 它允許專案儘早釋出。
  • 如果專案被廢棄,它不會佔用名稱。
  • 它不會阻礙未來的變化。當專案成熟且沒有理由保留個人所有權時,仍然可以重新命名專案

使用單一名稱

每個專案只分發一個包(或一個模組),並使用包(或模組)名稱作為專案名稱。

  • 它避免了專案名稱與分發包或模組名稱之間可能產生的混淆。
  • 它使名稱保持一致。
  • 它是明確的:當看到專案名稱時,可以猜測包/模組名稱,反之亦然。
  • 它還限制了包/模組名稱之間的隱式衝突。透過使用單一名稱,當您在PyPI上註冊專案名稱時,您也執行了基本的包/模組名稱可用性驗證。

    例如,pipelinepython-pipelinedjango-pipeline 都分發了一個名為“pipeline”的包或模組。因此,安裝其中兩個會導致錯誤。如果這些分發使用單一名稱,則不會發生此問題。

  • 包名稱:“kheops.pyramid”,即 import kheops.pyramid
  • 專案名稱:“kheops.pyramid”,即 pip install kheops.pyramid

  • 包名稱:“kheops”
  • 專案名稱:“KheopsPyramid”

注意

由於歷史原因,PyPI 包含許多專案和分發包/模組名稱不同的分發。

多個包/模組應該很少見

從技術上講,Python 分發可以提供多個包和/或模組。有關詳細資訊,請參閱安裝指令碼參考

有些分發確實如此。例如,setuptoolsdistribute 都聲明瞭“pkg_resources”、“easy_install”和“site”模組,此外還有各自的“setuptools”和“distribute”包。

將此用例視為例外。在大多數情況下,您不需要此功能。因此,一個分發應該一次只提供一個包或模組。

不同的名稱應該很少見

使用單一名稱規則的一個顯著例外是當您明確需要不同名稱時。

例如,Pillow 專案提供了原始 PIL 分發的替代方案。這兩個專案都分發一個“PIL”包。

將此用例視為例外。在大多數情況下,您不需要此功能。因此,分發包名稱應與專案名稱相同。

遵循PEP 8中包和模組名稱的語法

PEP 8 適用於 Python 包和模組的名稱。

如果您使用單一名稱,那麼 PEP 8 也適用於專案名稱。例外情況是名稱空間包,專案名稱中需要點。

選擇令人難忘的名稱

專案名稱的一件重要事情是它要令人難忘。

例如,celery 不是一個有意義的名稱。最初,它不明顯是關於訊息佇列的。但它令人難忘,部分原因是可以用來餵養一個RabbitMQ伺服器。

選擇有意義的名稱

問問自己“我將如何用一句話描述這個名稱的用途?”,然後“有人能透過檢視名稱來猜測嗎?”

例如,DateUtils 是一個有意義的名稱。它顯然是處理日期實用程式的。

當您使用名稱空間時,儘量使每個部分都具有意義。

使用打包元資料

將專案名稱視為 PyPI 上的唯一識別符號

  • 重要的是這些識別符號保持人類可讀。
  • 如果這些識別符號有意義,那就更好了。
  • 但識別符號的主要目的不是對專案進行分類或描述。

分類器和關鍵詞元資料用於分發的分類。 摘要和描述元資料用於描述專案。

例如,有一個“Framework :: Twisted”分類器。即使名稱相當異構(它們不遵循特定模式),我們仍然可以獲得列表。

為了組織社群貢獻,關於名稱和名稱空間的約定很重要,但關於元資料的約定應該更重要。

例如,我們可以在許多地方找到 Plone 小部件

  • plone.portlet.*
  • collective.portlet.*
  • collective.portlets.*
  • collective.*.portlets
  • 一些與供應商相關的專案,如“quintagroup.portlet.cumulus”
  • 甚至名稱中沒有出現“portlet”模式的專案。

即使 Plone 社群有約定,使用名稱來分類分發也是不合適的。透過過濾名稱,無法獲得提供 Plone 小部件的所有分發的完整列表。但如果所有這些分發都使用“Framework :: Plone”分類器和“portlet”關鍵字,那將是可能的。

避免深度巢狀

Python之禪說“扁平優於巢狀”。

兩層幾乎總是足夠的

不要在深層巢狀的層次結構中定義所有內容:您最終會得到諸如“pythonsport.common.maps.forest”之類的專案和包。這種型別的名稱既冗長又笨重(例如,如果您從包中匯入很多內容)。

此外,大型層次結構往往會隨著時間的推移而崩潰,因為不同包之間的界限變得模糊不清。

共識是優先使用兩層巢狀。

例如,我們有 plone.principalsource 而不是 plone.source.principal 或類似的東西。名稱更短,包結構更簡單,並且在這裡擁有三層巢狀幾乎沒有任何好處。試圖將所有“核心 Plone”源(源是一種詞彙表)放入 plone.source.* 名稱空間是不切實際的,部分原因是一些源是其他包的一部分,部分原因是因為源已經存在於其他地方。如果我們建立了一個新的名稱空間,它從一開始就會被不一致地使用。

是:“pyranha”

是:“pythonsport.climbing”

是:“pythonsport.forestmap”

否:“pythonsport.maps.forest”

所有權只使用一層

不要使用3層來在社群名稱空間中設定個人/組織所有權。

例如,讓我們考慮

  • 您正在插入一個社群名稱空間,例如“collective”。
  • 您想新增一個更嚴格的“所有權”級別,以避免社群內部的衝突。

在這種情況下,您最好將最嚴格的所有權級別作為第一層。

例如,其中“collective”是“gergovie”所屬的主要社群名稱空間,“vercingetorix”是“gergovie”作者的名字

否:“collective.vercingetorix.gergovie”

是:“vercingetorix.gergovie”

不要使用名稱空間層進行分類

請改用打包元資料

不要使用超過3層

從技術上講,您可以建立深度巢狀的層次結構。但是,在大多數情況下,您不應該需要它。

注意

即使是名稱空間是標準的社群,也不使用超過3層。

在PyPI上註冊名稱

PyPI 是 Python 社群中分發的中心位置。因此,它也是註冊專案和包名稱的地方。

有關詳細資訊,請參閱向包索引註冊

方法

以下方法將幫助您遵循上述指南和約定。

如何檢查名稱可用性?

在選擇專案名稱之前,請確保它尚未在以下位置註冊

  • PyPI
  • 就是這樣。PyPI是唯一的官方場所。

例如,您也可以在各種位置(如流行的程式碼託管服務)進行檢查,但請記住,PyPI是您在Python社群中可以**註冊**名稱的唯一地方。

這就是為什麼在PyPI上註冊名稱很重要的原因。

還要確保已分發包或模組的名稱尚未註冊

使用單一名稱規則也有助於您避免與包名稱衝突:如果專案名稱可用,那麼包名稱也很可能可用。

如何重新命名專案?

重新命名專案是可能的,但請記住這會造成一些混淆。因此,請特別注意 README 和文件,以便使用者理解發生了什麼。

  1. 首先,不要從 PyPI 中刪除舊的分發。因為有些使用者可能正在使用它們。
  2. 複製舊專案,然後更改名稱(專案和包/模組)。至少要注意
    • 打包檔案,
    • 包含原始檔的資料夾名稱,
    • 文件,包括 README,
    • 程式碼中的匯入語句。
  3. 在 setup.cfg 檔案中為新分發分配 Obsoletes-Dist 元資料。請參閱 PEP 345 關於 Obsolete-Distsetup.cfg 規範
  4. 釋出重新命名專案的新版本,然後釋出它。
  5. 編輯舊專案
    • 新增對新專案的依賴,
    • 刪除除打包內容之外的所有內容,
    • 在安裝指令碼中新增 Development Status :: 7 - Inactive 分類器,
    • 釋出新版本。

因此,舊包的使用者

  • 可以繼續使用已棄用版本的舊分發,
  • 可以升級到舊分發的最新版本,該版本是空的……
  • ...並自動下載新的分發作為舊分發的依賴項。

發現舊專案的使用者會看到它處於非活動狀態。

改進PyPI上重新命名專案的處理

如果許多專案都遵循重新命名指南,那麼許多舊的分發將具有以下特徵

  • Development Status :: 7 - Inactive 分類器。
  • 最新版本為空,除了打包內容。
  • 最新版本“重定向”到另一個分發。例如,它對重新命名專案具有單一依賴關係。
  • 在較新的分發中被引用為Obsoletes-Dist

因此,將能夠檢測重新命名的專案並提高 PyPI 的可讀性。這樣使用者就可以專注於活動分發。但目前不需要此功能。沒有緊迫性。本文件中將不涉及此內容。

如何將命名指南應用於現有專案?

現有專案沒有義務重新命名。出於顯而易見的原因,選擇權留給專案作者和維護者。

但是,邀請專案作者

關於當前命名的說明

首先,重要的是您要說明當前的選擇

  • 問問自己“我為什麼選擇當前名稱?”,然後記錄下來。
  • 如果與本文件中提供的指南有差異,您應該告知您的使用者。
  • 如果可能,請在專案的錯誤跟蹤器中建立問題,至少作為記錄。然後您可以稍後解決它們,或者可能將其標記為“wontfix”。

旨在接收社群貢獻的專案也應該組織社群貢獻

促進遷移

每個 Python 開發者都應儘可能遷移,或在其各自的社群中推廣遷移。

將這些指南應用於您的專案,然後社群就會看到它是安全的。

特別是,“領導者”,如流行專案的作者,具有影響力,他們擁有權力,因此對社群負有責任。

將這些指南應用於流行專案,然後社群也會採納這些約定。

專案應在釋出新(主要)版本時促進遷移,特別是如果此版本引入了對 Python 3.x、新標準庫的打包或名稱空間包的支援

機會

隨著 Python 3.3 的開發

  • 許多專案不相容 Python 3.x。這包括“大型”產品或框架。這意味著許多專案將不得不進行遷移以支援 Python 3.x。
  • 打包(又稱 distutils2)正在啟動。釋出後,專案將被邀請遷移並使用新的打包。
  • PEP 420 為 Python 帶來了名稱空間包的官方支援。

這意味著大多數活躍專案將在未來一年內遷移以支援 Python 3.x、新打包或新名稱空間包。

這樣的機會是獨一無二的,不會很快再次出現!所以讓我們儘快(即現在)引入和推廣命名約定。

參考資料

額外背景

參考文獻和腳註


來源:https://github.com/python/peps/blob/main/peps/pep-0423.rst

最後修改:2025-05-03 18:09:21 GMT