如何利用果蠅記憶成為一名高效程序員?
譯文作者 | Hynek Schlawack
譯者 | 李睿
審校 | 諾亞
在自然界中,果蠅可以根據(jù)圖形本身所具有的一些參數(shù)來完成對(duì)相應(yīng)視覺圖形的識(shí)別并形成記憶,例如大小、顏色、高度和圖形朝向等參數(shù)。
多年的編程經(jīng)歷
Hynek Schlawack是一名經(jīng)驗(yàn)豐富的德國軟件工程師,他積極參與開源軟件的開發(fā),如今已成為Python軟件基金會(huì)成員。他表示,與上世紀(jì)90年代中期開始使用Amiga BASIC時(shí)相比,如今的編程技術(shù)和方法變得更加多樣化。如果那時(shí)購買一本關(guān)于計(jì)算機(jī)編程書籍,這本書可能包含99%的內(nèi)容,并且書中隨處都有注釋和專用標(biāo)記,而學(xué)習(xí)者根據(jù)書中的描述邊學(xué)習(xí)邊操作。
如今,有關(guān)前端Web框架的書籍可能比C64可執(zhí)行文件程序員編寫完整的游戲所需的書籍還要厚。另一方面,了解編寫代碼所需的所有信息通常只需點(diǎn)擊鼠標(biāo)搜索一下即可。
現(xiàn)在很少有人為開發(fā)人員文檔付費(fèi),微軟和蘋果都在網(wǎng)絡(luò)上免費(fèi)為所有人提供他們的文檔,更不用說免費(fèi)的開源項(xiàng)目。
在npm、PyPI和GitHub時(shí)代,很難解釋要求超出操作系統(tǒng)提供的任何東西,這曾經(jīng)是一個(gè)有爭(zhēng)議的決定,必須明智地權(quán)衡。通常是將依賴項(xiàng)與產(chǎn)品一起交付。
新的可用性很好,種類也很豐富,但這會(huì)導(dǎo)致生產(chǎn)所需信息的碎片化。
例如,人們打開了幾十個(gè)標(biāo)簽,上面有他們當(dāng)前使用的軟件包文檔,并忙著在它們之間進(jìn)行切換以找到合適的軟件包。而在某些場(chǎng)合,有成千上萬的人共享一個(gè)POP,但是只有在線文件才會(huì)成為一個(gè)問題,除非互聯(lián)網(wǎng)完全消失。尤其是互聯(lián)網(wǎng)不穩(wěn)定的在線搜索功能比沒有搜索功能更糟糕。
如果開發(fā)人員可以使用多種編程語言,每種語言都有巨大的子社區(qū)(即使在Python中,F(xiàn)lask+SQLAlchemy+Postgres與編寫基于異步的網(wǎng)絡(luò)服務(wù)器是完全不同的事情),記住使用的每種方法的參數(shù)是讓人頭疼的事情。
Schlawack表示,這就是為什么2012年發(fā)現(xiàn)Dash對(duì)他來說是一件改變?nèi)松拇笫碌脑颉?/p>
API文檔瀏覽器

Dash搜索
Dash讓開發(fā)人員擁有按下鍵盤按鍵就可以獲得所有相關(guān)API的超能力:
- 按下“空格”鍵,彈出一個(gè)浮動(dòng)窗口,上面有一個(gè)激活的搜索欄。
- 開始輸入API或主題的大概名稱。
- 從建議中選擇并登陸官方項(xiàng)目文檔中的符號(hào)。
- 按下Esc鍵,浮動(dòng)窗口消失,可以立即開始輸入代碼,因?yàn)榫庉嬈髟俅纬蔀榻裹c(diǎn)。
- 如果忘記了剛剛閱讀的內(nèi)容,再次按空格鍵,窗口會(huì)在同一位置彈出。
這一切都快得令人難以置信,在2秒內(nèi)完成一次這樣的往返。但它必須那么快,這樣開發(fā)人員才不會(huì)忘記在做什么。在這一點(diǎn)上,開發(fā)人員可以潛意識(shí)地做到。這是原生應(yīng)用程序被遺忘的幸福。
而按下按鍵獲得所有API文檔的能力是非常強(qiáng)大的。
開發(fā)人員在記住函數(shù)參數(shù)或類的導(dǎo)入路徑上花費(fèi)的精力越少,那么在思考正在解決的問題上的精力就越多。
雖然Dash是一個(gè)訂閱費(fèi)用為30美元的Mac應(yīng)用程序(也可作為Setapp訂閱的一部分提供),但還有一個(gè)名為Zeal的免費(fèi)Windows和Linux版本,以及一個(gè)名為Velocity的20美元的Windows應(yīng)用程序。當(dāng)然,還有一個(gè)Emacs包在做同樣的事情:helm-dash。
以下只關(guān)注Dash,因?yàn)檫@就是Schlawack正在使用的程序,但除非另有說明,否則它適用于所有這些。它們的共同點(diǎn)是本地文檔的格式。
文檔集
它們都使用Apple的文檔集捆綁包(docsets),這些文檔集是包含HTML文檔、基于XML的屬性列表中的元數(shù)據(jù)和SQLite數(shù)據(jù)庫中的搜索索引的目錄:

如果在硬盤中有很多HTML文件,可以將其轉(zhuǎn)換為Dash可以使用的文檔集。它只是帶有元數(shù)據(jù)的HTML文件。由于它是硬盤上的HTML文件,因此所有這些都可以脫機(jī)運(yùn)行。
因此,文檔集可以替換已經(jīng)保存在本地計(jì)算機(jī)上的文檔,以便更快訪問,而無需做任何特別的事情。只需將其打包成必要的目錄結(jié)構(gòu),添加一個(gè)空索引,并填寫簡(jiǎn)單的元數(shù)據(jù)。
現(xiàn)在可以通過一個(gè)按鍵來調(diào)用它們,然后用另一個(gè)按鍵來取消。
Schlawack表示,他每天都在大量平臺(tái)上開發(fā)項(xiàng)目。而且在這里談?wù)摰牟粌H僅是編程API:Ansible角色、CSS類、HAProxy配置、Postgres(和SQL)特性……

已安裝的Dash文檔集
雖然Python和Go核心文檔隨Dash一起提供,而Godoc文檔可以通過URL直接添加 ,無論Dash的功能多么強(qiáng)大:在現(xiàn)代軟件開發(fā)的碎片化世界中,它永遠(yuǎn)無法提供所需要的一切。

Sphinx
Schlawack表示,對(duì)他來說最大的差距是基于Sphinx的文檔主導(dǎo)Python生態(tài)系統(tǒng)。
Sphinx是一個(gè)與編程語言限制的文檔編寫框架。不僅僅是API文檔或敘述性文檔:所有這些具有豐富的相互鏈接。它曾經(jīng)因?qū)eStructuredText強(qiáng)加給用戶而臭名昭著,但現(xiàn)在越來越多的項(xiàng)目使用出色的MyST包在Markdown中執(zhí)行這一操作。如果有人對(duì)Sphinx文檔的外觀有任何偏見,建議訪問Sphinx主題庫,可以看看其文檔有多漂亮。它是用Python編寫的,但被廣泛使用,包括Apple的Swift、LLVM(Clang!)項(xiàng)目或廣受歡迎的PHP項(xiàng)目。
它提供了準(zhǔn)確的缺失部分:API條目、部分、詞匯表術(shù)語、配置選項(xiàng)、命令行參數(shù)等的索引——所有這些都以開發(fā)人員喜歡的方式分布在文檔中,但始終可以相互鏈接。如果遵循像“Diátaxis”這樣的系統(tǒng)框架,那么會(huì)覺得這非常棒。
從技術(shù)上說,實(shí)現(xiàn)這一點(diǎn)的關(guān)鍵組件只是一個(gè)擴(kuò)展:interphinx。最初用于項(xiàng)目間鏈接(因此而得名),它提供了一個(gè)機(jī)器可讀索引供開發(fā)人員使用。該索引變得如此流行,現(xiàn)在得到了MkDocs擴(kuò)展mkdocstrings和pydoctor的支持。可以通過索引文件objects.inv準(zhǔn)確識(shí)別與intershinx兼容的文檔。
這就是Schlawack在10年前開始采用doc2dash開發(fā)項(xiàng)目的原因。

doc2dash
doc2dash是一個(gè)命令行工具,可以從Homebrewtap中獲取,從其發(fā)布頁面下載適用于Linux、macOS和Windows的預(yù)構(gòu)建二進(jìn)制文件之一,或從PyPI安裝。
然后,所要做的就是將它指向一個(gè)包含intersphinx兼容文檔的目錄,它將執(zhí)行所有必要的操作,并提供一個(gè)文檔集。

doc2dash轉(zhuǎn)換
需要注意,其名稱是doc2dash而不是sphinx2dash。它始終被用作編寫高質(zhì)量轉(zhuǎn)換器的框架,第一個(gè)是Sphinx和pydoctor。遺憾的是,這種希望沒有實(shí)現(xiàn),因?yàn)榭梢岳斫獾氖?,每個(gè)社區(qū)都想使用自己的語言和工具。
不過,這些工具通常是一次性的,所以Schlawack再次強(qiáng)調(diào),愿意與其他人一起合作,為其他文檔格式添加支持。因此不要重新發(fā)明輪子,框架就在那里,而這只是一堆代碼。
Dash和doc2dash已經(jīng)存在了十多年,仍然看到打開的數(shù)不勝數(shù)的API文檔標(biāo)簽頁。開發(fā)人員一直在向人們展示Dash的實(shí)際應(yīng)用。
雖然本文的果蠅部分到此結(jié)束,但將繼續(xù)為循序漸進(jìn)的操作方法提供幫助。
如何轉(zhuǎn)換和提交文檔
這一指南的目的是讓人們學(xué)會(huì)如何將與intersphinx兼容的文檔轉(zhuǎn)換為文檔集,以及如何將其提交到Dash的用戶生成的文檔集注冊(cè)表。
假設(shè)用戶已經(jīng)選擇并安裝了API瀏覽器。使用哪一個(gè)并不重要,但這個(gè)方法使用Dash。要在最后選擇性地提交文檔集還需要對(duì)GitHub及其拉取請(qǐng)求工作流程有基本的了解。
Schlawack利用這個(gè)指南,先從structlog開始,最終開始發(fā)布其項(xiàng)目的文檔集。建議用戶選擇一個(gè)與intershinx兼容的項(xiàng)目,該項(xiàng)目并不受Dash支持,并且用戶經(jīng)常訪問其文檔的選項(xiàng)卡。
那么現(xiàn)在可以開始了。

獲取doc2dash
如果用戶已經(jīng)在使用Homebrew,獲取doc2dash的最簡(jiǎn)單方法是使用這個(gè)tap:
$ brew install hynek/tap/doc2dash
在x86-64和Apple silicon上都有針對(duì)Linux x86-65和macOS的預(yù)構(gòu)件,因此安裝速度應(yīng)該非???。
除非熟悉Python打包方式,否則下一個(gè)最佳方式是從發(fā)布頁面預(yù)構(gòu)建二進(jìn)制文件。目前,它提供適用于Linux、Windows和macOS的二進(jìn)制文件,這些全部基于x86-64。如果這被證明很受歡迎,希望將來能提供更多。
最后,可以從PyPI中獲取它。建議使用pipx并且使用它運(yùn)行doc2dash的最簡(jiǎn)單方法是:
$ pipx run doc2dash --help
注:如果知道PyPy是什么,如何使用它,并計(jì)劃轉(zhuǎn)換龐大的文檔樹:在PyPy上doc2dash的速度是在CPython上的兩倍多。
如果對(duì)此一無所知,則可以忽略這些。

構(gòu)建文檔
接下來是doc2dash的最大問題和頻繁功能請(qǐng)求的來源:需要一個(gè)完整的內(nèi)置文檔。通常這意味著必須下載存儲(chǔ)庫,并在安裝doc2dath之前弄清楚如何構(gòu)建文檔,因?yàn)榇蠖鄶?shù)文檔站點(diǎn)都不提供整個(gè)文檔的下載。
這里的建議是首先查找tox.ini或noxfile.py,并查看它是否構(gòu)建了文檔。如果沒有,可以查找readthedocs.yml,即使這讓人失望,也會(huì)尋找名為docs-requirements.txt的文件或可選的安裝目標(biāo)(如docs)。最后的希望是瀏覽YAML頁面并檢查CI配置。
一旦設(shè)法安裝了所有依賴項(xiàng),通常只需在文檔目錄中創(chuàng)建html即可。
在弄清楚這一點(diǎn)后,應(yīng)該有一個(gè)名為_build/html的目錄用于Sphinx或名為MkDocs的站點(diǎn)。
需要注意MkDocs,如果項(xiàng)目不使用mkdocstrings擴(kuò)展,就不會(huì)有objects.inv文件,因此沒有要使用的API數(shù)據(jù)。
真的希望將來有更多基于MkDocs的項(xiàng)目添加對(duì)mkdocstrings的支持!與Sphinx一樣,它與語言無關(guān)。

轉(zhuǎn)換
最困難的一步也是最簡(jiǎn)單的一步:將剛剛構(gòu)建的文檔轉(zhuǎn)換為文檔集。
所要做的就是將doc2dash指向帶有HTML文檔的目錄并等待:
$ doc2dash _build/html
doc2dash知道如何從intersphinx索引中提取名稱,并默認(rèn)使用它(可以使用--name覆蓋它)。應(yīng)該能夠?qū)⑦@一文檔集添加到選擇的API瀏覽器中,并且一切正常。
如果通過--add-to-dash或-a,最終的文檔集會(huì)在完成后自動(dòng)添加到Dash。如果傳遞--add-to-global或-A,它會(huì)將完成的文檔集移動(dòng)到全局目錄(~/Library/ApplicationSupport/doc2dash/DocSets)并從那里添加。在創(chuàng)建文檔集時(shí),很少在沒有-A的情況下運(yùn)行doc2dash。

改進(jìn)文檔集
Dash的文檔有很多關(guān)于如何改進(jìn)在上一步中構(gòu)建的文檔集的建議。重要的是要注意以下五個(gè)步驟是嚴(yán)格可選的。
但在這種情況下,可以將文檔集提交到Dash的用戶貢獻(xiàn)注冊(cè)表。
設(shè)置主頁
使用Dash,始終可以搜索所有已安裝的文檔集,但有時(shí)希望限制搜索范圍。例如,當(dāng)鍵入p3:(冒號(hào)很重要)時(shí),切換到僅搜索Python3文檔集。在開始輸入之前,它會(huì)在搜索框下方為提供一個(gè)菜單,其第一項(xiàng)是“主頁”。
在轉(zhuǎn)換structlog文檔時(shí),這個(gè)主頁是有用的索引,但通常不是想要的。當(dāng)打開主頁時(shí),通常瀏覽敘述文檔。
設(shè)置主頁的doc2dash選項(xiàng)是--index-page或-I,并采用要使用的頁面的文件名,以對(duì)應(yīng)文檔根目錄。
令人困惑的是,索引的文件名是genindex.html,而主頁的文件名是HTML典型的index.html。因此,將--index-pageindex.html添加到命令行。
添加圖標(biāo)
文檔集可以有圖標(biāo),這些圖標(biāo)顯示在文檔集名稱和符號(hào)旁邊的虛線中。這很好,并且也有助于更快地識(shí)別文檔集,如果要跨多個(gè)文檔集進(jìn)行搜索,其中有一個(gè)符號(hào)。
structlog有一個(gè)可愛的海貍標(biāo)志,所以使用ImageMagick將標(biāo)志調(diào)整為16x16像素:
$ magick \
docs/_static/structlog_logo_transparent.png \
-resize 16x16 \
docs/_static/docset-icon.png
現(xiàn)在可以使用--icondocset-icon.png選項(xiàng)將它添加到文檔集中。
支持在線重定向
離線文檔很棒,但有時(shí)跳轉(zhuǎn)到正在閱讀的文檔頁面的在線版本可能會(huì)很有用。一個(gè)常見的原因是仔細(xì)閱讀更新或舊版本。
Dash有菜單項(xiàng)“OpenOnlinePage??B”,但它需要知道文檔的基本URL??梢允褂?-online-redirect-url或-u進(jìn)行設(shè)置。
對(duì)于Read the Docs上的Python包,可以在stable(最后一個(gè)VCS標(biāo)記)或latest(當(dāng)前主分支)之間進(jìn)行選擇。
Latest可能更有意義,如果離開離線文檔,因此將添加:
--online-redirect-url https://www.structlog.org/en/latest/
將所有內(nèi)容放在一起
終于完成了!運(yùn)行整個(gè)命令行,看看它在Dash中的樣子:
$ doc2dash \
--index-page index.html \
--icon docs/_static/docset-icon.png \
--online-redirect-url https://www.structlog.org/en/latest/ \
docs/_build/html
Converting intersphinx docs from '/Users/hynek/FOSS/structlog/docs/_build/html' to 'structlog.docset'.
Parsing documentation...
Added 238 index entries.
Patching for TOCs... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
這是一個(gè)精彩的主頁:

structlog的主頁
注意搜索欄中的圖標(biāo),然后在帶有任何錨點(diǎn)的任何頁面上按??B,將帶到最新版本的在線文檔中的相同位置。
自動(dòng)化
由于希望為每個(gè)新版本創(chuàng)建一個(gè)新版本的文檔集,因此需要自動(dòng)化創(chuàng)建。structlog已經(jīng)將GitHub Actions用作CI,因此也可以使用它來構(gòu)建文檔集。
對(duì)于本地測(cè)試,將利用doc2dash作為Python項(xiàng)目的優(yōu)勢(shì),并使用一個(gè)tox環(huán)境來重用在測(cè)試文檔本身時(shí)使用的依賴項(xiàng)。
tox是make和基于ini文件格式的虛擬環(huán)境管理器的組合。它最初的目的是在多個(gè)Python版本上測(cè)試Python軟件,但現(xiàn)在已經(jīng)變得更加強(qiáng)大。
Makefile的最大優(yōu)點(diǎn)是它更易于移植,并且支持內(nèi)置的Python打包(無論如何這對(duì)于構(gòu)建文檔都是必需的)。
安裝structlog[docs],即具有可選文檔依賴項(xiàng)的包,加上doc2dash。然后它按順序運(yùn)行命令:
[testenv:docset]
extras = docs
deps = doc2dash
allowlist_externals =
rm
cp
tar
commands =
rm -rf structlog.docset docs/_build
sphinx-build -n -T -W -b html -d {envtmpdir}/doctrees docs docs/_build/html
doc2dash --index-page index.html --icon docs/_static/docset-icon.png --online-redirect-url https://www.structlog.org/en/latest/ docs/_build/html
cp docs/_static/docset-icon@2x.png structlog.docset/icon@2x.png
tar --exclude='.DS_Store' -cvzf structlog.tgz structlog.docset
現(xiàn)在可以通過調(diào)用tox-e文檔集來構(gòu)建一個(gè)文檔集。在doc2dash支持高分辨率圖標(biāo)之前,它還將32x32像素大的徽標(biāo)版本直接復(fù)制到文檔集中。
在CI中這樣做很簡(jiǎn)單,但需要大量的樣板文件,所以只鏈接到工作流。注意最后的上傳工件操作,它允許從運(yùn)行摘要下載構(gòu)建的文檔集。
此時(shí),有了一個(gè)自動(dòng)構(gòu)建的很棒的文檔集。現(xiàn)在是對(duì)外分享的時(shí)候了!
提交
在最后一步中,會(huì)將文檔集提交到Dash的用戶貢獻(xiàn)的存儲(chǔ)庫,以便其他人可以從Dash的GUI輕松下載它。方便的是,Dash使用每個(gè)開源愛好者可能熟悉的整個(gè)過程的概念:GitHub拉取請(qǐng)求。
第一步是檢查Docset Contribution Checklist。幸運(yùn)的是,或者在某些情況下是doc2dash,已經(jīng)處理好了一切。
因此進(jìn)行下一步,并進(jìn)入https://github.com/Kapeli/Dash-User-Contributions存儲(chǔ)庫,并將其克隆的計(jì)算機(jī)上。
首先,必須將Sample_Docset目錄復(fù)制到docsets,并在執(zhí)行此操作時(shí)重命名它。因此,其命令行是:
$ cp -a Sample_Docset docsets/structlog
使用cddocsets/structlog進(jìn)入目錄并從那里進(jìn)一步獲取它。
主要步驟是添加文檔集本身,但要作為一個(gè)gzipped tar文件。貢獻(xiàn)指南甚至提供了創(chuàng)建它的模板。在這個(gè)例子中,命令行是:
$ tar --exclude='.DS_Store' -cvzf structlog.tgz structlog.docset
可能已經(jīng)注意到已經(jīng)在tox文件中完成了tar-ing,所以只需要復(fù)制它:
$ cp ~/FOSS/structlog/structlog.tgz .
它還希望將圖標(biāo)添加到文檔集中的內(nèi)容中,因此從它們的文檔集中復(fù)制:
$cp~/FOSS/structlog/structlog.docset/icon*。
接下來,在docset.html文件中填寫元數(shù)據(jù),這在例子中很簡(jiǎn)單:
{
"name": "structlog",
"version": "22.1.0",
"archive": "structlog.tgz",
"author": {
"name": "Hynek Schlawack",
"link": "https://github.com/hynek"
},
"aliases": []
}最后,寫一些關(guān)于我們是誰以及如何構(gòu)建文檔集的文檔。在查看了其他示例后,確定了以下內(nèi)容:
# structlog
<https://www.structlog.org/>
Maintained by [Hynek Schlawack](https://github.com/hynek/).
## Building the Docset
### Requirements
- Python 3.10
- [*tox*](https://tox.wiki/)
### Building
1. Clone the [*structlog* repository](https://github.com/hynek/structlog).
2. Check out the tag you want to build.
3. `tox -e docset` will build the documentation and convert it into `structlog.docset` in one step.
tox技巧正在得到回報(bào)——不必向任何人解釋Python打包!
不要忘記從示例文檔集中刪除不使用的內(nèi)容:
$ rm -r versions Sample_Docset.tgz
終于完成了!檢查一下更改:
$ git checkout -b structlog
$ git add docsets/structlog
$ git commit -m "Add structlog docset"
[structlog 33478f9] Add structlog docset
5 files changed, 30 insertions(+)
create mode 100644 docsets/structlog/README.md
create mode 100644 docsets/structlog/docset.json
create mode 100644 docsets/structlog/icon.png
create mode 100644 docsets/structlog/icon@2x.png
create mode 100644 docsets/structlog/structlog.tgz
$ git push -u
這看起來不錯(cuò),那么現(xiàn)在是提出拉取請(qǐng)求的時(shí)候了!
在幾個(gè)小時(shí)之后將出現(xiàn)這一圖像:

在Dash中貢獻(xiàn)的structlog文檔集
終于獲得成功,現(xiàn)在每個(gè)人都可以下載structlog文檔集。
結(jié)束語
Schlawack表示,希望本文既激發(fā)了用戶對(duì)API文檔瀏覽器的興趣,又揭開了創(chuàng)建自己文檔集的神秘面紗。而其目標(biāo)是幫助在完成工作時(shí)必須牢記的所有軟件包的程序員。
他希望這篇文章能激發(fā)人們向doc2dash添加更多格式,以便更多的程序員能夠享受觸手可及的API文檔的樂趣。
在發(fā)表這篇文章后,Schlawack的另一個(gè)期望是Zeal重新煥發(fā)活力。根據(jù)行業(yè)媒體的報(bào)道,Zeal最后一次更新可以追溯到四年前,因?yàn)檫@是一個(gè)開源項(xiàng)目,如果能夠獲得新的客戶,就可能讓用戶在所有平臺(tái)上擁有良好的API瀏覽器。
原文鏈接:
?? https://hynek.me/articles/productive-fruit-fly-programmer/??






















