Python 小技巧:如何實(shí)現(xiàn)操作系統(tǒng)兼容性打包仆抵?

有一個(gè)這樣的問題:現(xiàn)要用 setuptools 把一個(gè)項(xiàng)目打包成 whl 文件,然后 pip install 在 Windows/Linux 兩種操作系統(tǒng)上,但是該項(xiàng)目中有一些依賴庫只有 Windows 上才有(例如 pywinauto诱鞠、pywingui、pywinrm)这敬,那么問題是航夺,如何實(shí)現(xiàn)打包文件的可兼容性安裝?

從打包的角度崔涂,這個(gè)問題的關(guān)鍵還是看 setup.py 和 requirements.txt 文件阳掐。

關(guān)于 Python 的包構(gòu)建分發(fā)和 setup.py 的使用,這里有篇文章 寫得很好冷蚂,推薦閱讀缭保。另外關(guān)于 Python 依賴庫的管理(requirements.txt),這篇文章 詳細(xì)比較了 pip蝙茶、pipreqs艺骂、pigar、pip-tools 和 pipdeptree 等工具隆夯,也推薦一讀钳恕。

有一個(gè)比較笨的實(shí)現(xiàn)方法:維護(hù)兩份 requirements.txt 文件,分別用來打包蹄衷,然后分發(fā)給不同操作系統(tǒng)去使用苞尝。

但是這樣會(huì)有麻煩:維護(hù)兩份依賴文件和兩種包文件,本身就挺費(fèi)勁的,而在生成過程中,每次還得對(duì)它們改名以作區(qū)分(注意包名有一定的規(guī)范約束睛廊,亂改的話,pip 可能識(shí)別不出)抡砂,維護(hù)成本就很高。

其實(shí)恬涧,維護(hù)軟件包在不同操作系統(tǒng)的版本注益,并不少見。如果你曾留意過不同版本 Python 庫文件的話溯捆,你會(huì)注意到很多庫都會(huì)按不同操作系統(tǒng)而分發(fā)不同的版本丑搔。例如,下面是同一版本號(hào)的 Numpy 在不同操作系統(tǒng)上的分發(fā)版(https://pypi.org/simple/numpy/):

image

可以看出它根據(jù) macos、linux 和 win 三類操作系統(tǒng)及其位數(shù)啤月,分成了 5 個(gè)版本煮仇。維護(hù)這么多版本,肯定是一件麻煩事谎仲,但是出現(xiàn)了這樣的結(jié)果浙垫,就意味著 Numpy 官方認(rèn)為分發(fā)不同系統(tǒng)版本是利大于弊的,而且是有辦法實(shí)現(xiàn)的郑诺。

回到我們的問題夹姥,是否有必要像 Numpy 那樣設(shè)法打包成多個(gè)操作系統(tǒng)定制的包呢?

答案是否定的辙诞。主要的原因:

  • Numpy 這么做是因?yàn)樗亲隹茖W(xué)計(jì)算的辙售,為了提升效率,它把編譯好的 C 拓展文件打包飞涂,從而不需要依賴環(huán)境上的 libxxx-devel 之類的庫圾亏。如果你編譯安裝過 Python,應(yīng)該有印象需要安裝 zlib-devel封拧、openssl-devel 和 libffi-devel 之類的系統(tǒng)依賴。但我們前面的問題比較簡(jiǎn)單夭问,并不是有不同的編譯依賴(系統(tǒng)級(jí))泽西,而只是三方庫依賴不同(項(xiàng)目級(jí))。
  • 另一個(gè)主要的原因缰趋,Numpy 打包出的不同系統(tǒng)版本捧杉,并非簡(jiǎn)簡(jiǎn)單單地用 setuptools 之類的 Python 庫就能打包,而是要借助標(biāo)準(zhǔn)的鏡像進(jìn)行構(gòu)建秘血。例如味抖,manylinux 版本的打包,參見 Github(https://github.com/pypa/manylinux)灰粮,就需要使用官方提供的 Docker 鏡像仔涩。對(duì)于我們的問題,顯然不想做到這么麻煩粘舟。

簡(jiǎn)而言之熔脂,根據(jù)前面的分析,如果要實(shí)現(xiàn)操作系統(tǒng)兼容的打包柑肴,維護(hù)多份依賴文件霞揉、使用不同構(gòu)建包的方法、維護(hù)多系統(tǒng)專用的包晰骑,方法可行适秩,但并不是很適用。

如果沒有新的辦法,這不失為一種考慮秽荞,但是有沒有別的辦法了呢骤公?

我曾被這個(gè)問題困擾過,但是沒有深入去研究解決蚂会,直到無意中在loguru 這個(gè)用來記錄日志的庫的 setup.py 中看到:

image

再翻看大名鼎鼎的requests 庫文件淋样,發(fā)現(xiàn)還可以這樣寫:

image

兩個(gè)示例都是寫在 setup.py 文件中,其實(shí)如果我們用 requirements.txt 文件胁住,也可以按這種格式寫趁猴,然后再讀取進(jìn)來。

這種神奇的寫法是怎么回事呢彪见?

它的依據(jù)是 2015 年 11 月創(chuàng)建的 PEP-508(以及相關(guān)的但已被撤銷或拒絕了的 PEP-390儡司、PEP-426、PEP-459余指、PEP-496)捕犬,該 PEP 的主要意圖是增強(qiáng) pip 等工具查找軟件包的能力。

image

比較重要的部分就是跟我們的問題相關(guān)的酵镜,即對(duì)操作系統(tǒng)作區(qū)分的標(biāo)識(shí)碉碉,相關(guān)的有:

image

有了這樣的擴(kuò)展支持,在打包依賴項(xiàng)時(shí)淮韭,就可以解決兼容性問題了垢粮。

例如 colorama 庫,如果我們只在 win32 系統(tǒng)才需要依賴靠粪,那么在打包時(shí)就可以指定:“colorama>=0.3.4 ; sys_platform=='win32' ”蜡吧;如果不需要限定 win32 系統(tǒng),而是在 windows 環(huán)境都安裝占键,那么可以寫成“colorama>=0.3.4 ; platform_system=='Windows' ”昔善。

最終,我們解決了本文開頭的問題畔乙。這個(gè)問題可能比較小眾君仆,解決起來也沒有什么大文章可做,算是一個(gè)小小的 tips 分享給大家吧牲距。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末袖订,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嗅虏,更是在濱河造成了極大的恐慌洛姑,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皮服,死亡現(xiàn)場(chǎng)離奇詭異楞艾,居然都是意外死亡参咙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門硫眯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕴侧,“玉大人,你說我怎么就攤上這事两入【幌” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵裹纳,是天一觀的道長(zhǎng)择葡。 經(jīng)常有香客問我,道長(zhǎng)剃氧,這世上最難降的妖魔是什么敏储? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮朋鞍,結(jié)果婚禮上已添,老公的妹妹穿的比我還像新娘。我一直安慰自己滥酥,他們只是感情好更舞,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坎吻,像睡著了一般缆蝉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上禾怠,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音贝搁,去河邊找鬼吗氏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛雷逆,可吹牛的內(nèi)容都是我干的弦讽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼膀哲,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼往产!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起某宪,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤仿村,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后兴喂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔼囊,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡焚志,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了畏鼓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酱酬。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖云矫,靈堂內(nèi)的尸體忽然破棺而出膳沽,到底是詐尸還是另有隱情,我是刑警寧澤让禀,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布挑社,位于F島的核電站,受9級(jí)特大地震影響堆缘,放射性物質(zhì)發(fā)生泄漏滔灶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一吼肥、第九天 我趴在偏房一處隱蔽的房頂上張望录平。 院中可真熱鬧,春花似錦缀皱、人聲如沸斗这。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽表箭。三九已至,卻和暖如春钮莲,著一層夾襖步出監(jiān)牢的瞬間免钻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工崔拥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留极舔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓链瓦,卻偏偏與公主長(zhǎng)得像拆魏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子慈俯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容