国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
是時候丟棄 Python 2.0,將 100 萬行的代碼遷移到Python 3.0了!


https://www.toutiao.com/i6606214656228852232/

Python 2 vs Python 3,究竟誰是性能之王?前段時間,Hackermoon 上一位叫 Anthony Shaw 的作者為我們做了一些測試,最終得出結(jié)論,雖然 Python 2 在加密和啟動時間測試過程中,比 Python 3 的速度更勝一籌,但整體而言,Python 3 更快。而這是否就意味著我們還是將項(xiàng)目代碼遷移到 Python 3.0 的好?接下來,本文來自全球著名的桌面應(yīng)用之一的 Dropbox 將分享他們要棄用 Python 2.0 的真實(shí)原因,以及如何將百萬行的代碼成功遷移至 Python 3。



Dropbox 是世界上流行的桌面應(yīng)用之一,你可以安裝在 Windows、macOS 和部分的 Linux 發(fā)行版上。但你可能不知道,這個應(yīng)用大部分是用 Python 寫的。實(shí)際上,Drew 給 Dropbox 寫下的第一行代碼就是用的 Windows 版 Python,用的是老牌的 pywin32 等庫。

雖然我們靠著 Python 2 支撐了這么多年(我們用過的最新版本是 Python 2.7),但我們從 2015 年就開始向 Python 3 轉(zhuǎn)換了。今天我們終于完成了轉(zhuǎn)換,你現(xiàn)在再裝 Dropbox 的話,那么它用的是 Dropbox 定制版本的 Python 3.5。本文將介紹這次史無前例的 Python 3 轉(zhuǎn)換的計(jì)劃、執(zhí)行和發(fā)布過程。



為什么選擇 Python 3?


Python 3 的接受度在 Python 社區(qū)一直是熱門話題?,F(xiàn)在雖然 Python 3 已經(jīng)廣為接受(http://py3readiness.org/),一些非常流行的項(xiàng)目如 Django 甚至完全放棄了 Python 2 的支持,但這個話題的熱度依然存在。對于我們來說,影響我們決定進(jìn)行轉(zhuǎn)換的幾個關(guān)鍵因素有:

引人入勝的新功能

Python 3 的創(chuàng)新十分迅速。除了一長列(http://whypy3.com/)正常的改進(jìn)(如 str 和 bytes 的討論),還有幾個功能吸引了我們的眼球:

  • 類型標(biāo)注語法:我們的代碼量非常大,所以類型標(biāo)注對于開發(fā)的效率非常重要。在 Dropbox 我們很喜歡 MyPy(http://mypy-lang.org/),因此原生的類型標(biāo)注支持對我們很有吸引力。
  • 并行函數(shù)語法:許多功能都極度依賴線程和消息傳遞,我們采用的是 Actor 模式,使用了 Future 模塊。而 asyncio 項(xiàng)目及其 async/await 語法有時能避免回調(diào)函數(shù),從而獲得更干凈的代碼。

過老的工具鏈

隨著 Python 2 日久年深,最初適合部署的工具鏈也大部分過時了。由于這些因素,繼續(xù)使用 Python 2 會帶來一系列的維護(hù)負(fù)擔(dān):

  • 過老的編譯器和運(yùn)行時使得我無法們升級一些重要更新。
  • 例如,我們在 Windows 和 Linux 上使用 Qt,而最新版本的 Qt 包含了 Chromium(通過 QtWebEngine 實(shí)現(xiàn)),因此需要更現(xiàn)代的編譯器。
  • 我們與操作系統(tǒng)的集成越來越深,而無法使用新版本的工具鏈,導(dǎo)致使用新版 API 的成本增大。
  • 例如,理論上 Python 2 依然需要 Visual Studio 2008 (http://stevedower.id.au/blog/building-for-python-3-5/)。但這個版本微軟已經(jīng)不再支持了,也與 Windows 10 SDK 不兼容。




凍結(jié)和腳本


當(dāng)初,我們依靠“凍結(jié)”腳本為我們支持的每個平臺創(chuàng)建原生應(yīng)用程序。但是,我們并沒有直接使用原生的工具鏈,如 macOS 的 Xcode,而是將創(chuàng)建各個平臺上的二進(jìn)制文件的任務(wù)交給其他程序去做,Windows 下是 py2exe,macOS 下是 py2app,Linux 下是 bbfreeze。這個完全面向 Python 的構(gòu)建系統(tǒng)收到了 distutils 的啟發(fā),因?yàn)槲覀兊膽?yīng)用最初只不過是個 Python 包,所以只需要一個類似于 setup.py 的腳本來構(gòu)建。

隨著時間的流逝,我們的代碼量越來越大?,F(xiàn)在,我們的開發(fā)已經(jīng)不僅僅使用 Python 開發(fā)了。實(shí)際上,我們的代碼現(xiàn)在由 TypeScript/HTML、Rust 和Python 混合組成,某些平臺上還用了 Objective-C 和 C++。為支持所有組件,setup.py 腳本(內(nèi)部的名字為 build-all.py)越來越大,越來越難以管理。

導(dǎo)火索就是我們與各個操作系統(tǒng)集成的方式。首先,我們越來越多地引入高級的 OS 擴(kuò)展,如 Smart Sync 的內(nèi)核組件等,這些組件不能,通常也不會使用 Python 編寫。其次,像微軟和蘋果等供應(yīng)商對部署應(yīng)用提出了新的需求,因此經(jīng)常需要用到新的、更復(fù)雜的工具,這些工具經(jīng)常是這些供應(yīng)商獨(dú)有的(比如代碼簽名等)。

例如在 macOS 上,10.10 版本引入了新的應(yīng)用擴(kuò)展以便與 Finder 進(jìn)行集成,就是FinderSync(https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/Finder.html)。它并不只是個 API,而是個完整的應(yīng)用程序包(.appex),有自己的生存中崛起規(guī)則(即它由 OS 啟動),而且對于進(jìn)程間通信的要求更嚴(yán)格。換句話說,使用 Xcode 就很容易集成這些擴(kuò)展,但 py2app 根本不支持它們。

因此,我們面臨著兩個問題:

  • 由于我們使用 Python 2,因此無法使用新的工具鏈,所以集成新的 API 的代價更高(比如使用Windows 10的Windows Runtime)。
  • 我們的凍結(jié)腳本使得部署原生代碼的代價更高(例如在 macOS 上構(gòu)建應(yīng)用擴(kuò)展)。

當(dāng)我們計(jì)劃轉(zhuǎn)換成 Python 3 時,我們面臨著兩個選擇:一是改進(jìn)凍結(jié)腳本中的依賴,以支持 Python 3(從而支持現(xiàn)代編譯器)和平臺相關(guān)的功能(如應(yīng)用程序擴(kuò)展),二是不再使用以 Python 為中心的構(gòu)建系統(tǒng),完全放棄凍結(jié)腳本。我們選擇了后者。

關(guān)于 pyinstaller 的一點(diǎn):我們認(rèn)真地思考過在項(xiàng)目早期使用 pyinstaller,但當(dāng)時它不支持 Python 3,而且更重要的是,它和其他凍結(jié)腳本有類似的限制。不管怎樣,這個項(xiàng)目本身很不錯,我們只是覺得不適合我們而已。



嵌入 Python

為了解決構(gòu)建和部署的問題,我們決定使用新的架構(gòu),在原生應(yīng)用中嵌入 Python 運(yùn)行時。我們不再將構(gòu)建過程交給凍結(jié)腳本處理,而是使用各個平臺自己的工具鏈(比如 Windows 下使用 Visutal Studio)來構(gòu)建各種入口點(diǎn)。進(jìn)一步,我們將 Python 代碼抽象到一個庫中,從而為多種語言“混合”的方式提供更直接的支持。

這樣我們就可以直接使用各個平臺的 IDE 和工具鏈了(例如可以直接添加原生的構(gòu)建目標(biāo),如 macOS 上的 FinderSync),同時保留使用 Python 編寫大部分應(yīng)用程序邏輯的能力。

我們最后采用了下面的結(jié)構(gòu):

  • 原生入口點(diǎn):這些與各個平臺的應(yīng)用程序模型兼容。
  • 其中包括應(yīng)用程序擴(kuò)展,如 Windows 下的 COM 組件和 macOS 下的應(yīng)用程序擴(kuò)展。
  • 共享庫可以使用多種語言編寫(包括 Python)。

表面上,這個應(yīng)用能夠更接近平臺的要求,而在各個庫的背后,我們可以有更大的靈活性來選擇自己喜歡的語言和工具。

這種架構(gòu)能提高模塊性,同時還帶來一個關(guān)鍵的副作用:現(xiàn)在可以同時部署 Python 2 庫和 Python 3 庫了。聯(lián)系到 Python 3 轉(zhuǎn)換工作,我們的轉(zhuǎn)換過程就需要兩步:第一,給 Python 2 實(shí)現(xiàn)新的架構(gòu);第二,利用它將 Python 2 替換成 Python 3。



第一步:“解凍”


第一步就是停止使用凍結(jié)腳本。目前,bbfreeze 和 pywin32 都不支持 Python 3,所以我們別無選擇。我們從 2016 年開始逐步進(jìn)行這項(xiàng)改變。

首先,我們將配置 Python 運(yùn)行時的工作抽象化,將 Python 的東西放到一個新的庫中,名為 libdropbox_bootstrap。這個庫會代替一些凍結(jié)腳本提供的功能。盡管我們不再需要這些腳本,但它們?nèi)匀惶峁┝艘恍┻\(yùn)行 Python 代碼所需的最基本的東西:

打包代碼以便在設(shè)備上執(zhí)行

這樣我們才能發(fā)布編譯好的 Python 字節(jié)碼,而不用發(fā)布 Python 源代碼。由于以前的每個凍結(jié)腳本在各個平臺上有各自的格式,我們利用這個機(jī)會引入了一種新的格式,用于在所有平臺上打包代碼使用:

  • 所有 Python 模塊的 Python 的字節(jié)碼 .pyc 都放在單一的 zip 文檔中(如 python-packages-35.zip)。
  • 原生擴(kuò)展. pyd / .so 由于是平臺相關(guān)的原生動態(tài)鏈接庫,他們必須安裝在特定的位置,保證應(yīng)用程序能毫無障礙地加載。
  • Windows 下,這些文件與入口點(diǎn)(即 Dropbox.exe)放在一起。
  • 打包通過優(yōu)秀的 modulegraph(作者是 py2app 和 PyObjC 的作者 Ronald Oussoren)實(shí)現(xiàn)。

隔離 Python 解釋器

這樣能阻止我們的應(yīng)用程序在設(shè)備上運(yùn)行其他的 Python 源代碼。有意思的是,Python 3 使得這種嵌入變得容易得多了。例如,新的 Py_SetPath 函數(shù)(https://docs.python.org/3/c-api/init.html#c.Py_SetPath)能夠讓我們將代碼隔離,不需要再像 Python 2 時代在凍結(jié)腳本中進(jìn)行某種復(fù)雜的隔離操作了。為了在 Python 2 中支持這一功能,我們在定制版本的 Python 2 中向下移植了這一功能。

其次,我們使用了平臺相關(guān)的入口點(diǎn)Dropbox.exe、Dropbox.app和dropboxd 來使用這個庫。這些入口點(diǎn)都是用各自平臺的“標(biāo)準(zhǔn)”工具編譯的,即 Visual Studio、Xcode 和 make,沒有使用 distutils。這樣我們就可以去掉凍結(jié)腳本帶來的大量修補(bǔ)工作了。例如,在 Windows 下,這一步大大簡化,只需為 Dropbox.exe 配置 DEP/NX 即可,就能將應(yīng)用程序裝箱單和資源嵌入了。

關(guān)于 Windows 的一點(diǎn)說明:現(xiàn)在,繼續(xù)使用 Visual Studio 2008 的代價已經(jīng)非常高了。為了正確地轉(zhuǎn)換,我們需要一個能同時支持 Python 2 和 Python 3 的版本,最終我們采用了 Visual Studio 2013。為支持它,我們進(jìn)一步修改了定制版本的 Python 2,使之能正確在 Visual Studio 2013 下編譯。這些修改的代價進(jìn)一步證明,我們轉(zhuǎn)換到 Python 3 的決定是正確的。



第二步:混合


成功地轉(zhuǎn)換如此之大(包含大約 100 萬行 Python 代碼)、安裝量如此之高(大約有幾億安裝)的應(yīng)用程序需要逐步進(jìn)行。我們不能簡單地在某次發(fā)布中“改變一個開關(guān)”來實(shí)現(xiàn)轉(zhuǎn)換,特別是我們的發(fā)布過程要求每兩個星期給所有用戶發(fā)布一個新版本。因此,必須找到一種辦法,將 Python 3 的部分轉(zhuǎn)換發(fā)布給一小部分用戶,以便檢測并修改 Bug。

為達(dá)到這一點(diǎn),我們決定實(shí)現(xiàn)用 Python 2 和 Python 3 同時編譯 Dropbox。這要求做到以下兩點(diǎn):

  • 能夠同時發(fā)布 Python 2 和 Python 3 的“包”,包括字節(jié)碼和擴(kuò)展,兩者必須能夠并存。
  • 在轉(zhuǎn)換過程中強(qiáng)制使用混合的 Python 2 / 3 語法。

我們采用上一步引入的嵌入式設(shè)計(jì)來實(shí)現(xiàn):將 Python 代碼抽象到庫和包中,就能很容易地引入另一個版本。這樣入口點(diǎn)程序(即 Dropbox.exe)就可以在初始化的早期控制選擇哪個 Python 版本了。

我們通過手動連接入口點(diǎn)程序到 libdropbox_bootstrap 來實(shí)現(xiàn)這一點(diǎn)。例如在 macOS 和 Linux 下,我們在 Python 版本確定之后使用 dlopen/dlsym 來加載。在 Windows 下,使用 LoadLibrary 和 GetProcAddress。

對 Python 解釋器的選擇必須在 Python 加載之前完成,因此為了使之更順暢,我們實(shí)現(xiàn)了命令行參數(shù) /py3 用于開發(fā),和一個保存在硬盤上的永久設(shè)置,以便通過我們的功能切換系統(tǒng)Stormcrow(https://blogs.dropbox.com/tech/2017/03/introducing-stormcrow/)來控制。

有了這些,我們就能在啟動 Dropbox 客戶端時動態(tài)選擇 Python 版本了。這樣就可以在 CI 基礎(chǔ)設(shè)施中設(shè)置額外的任務(wù)來針對 Python 3 運(yùn)行單元測試和集成測試。我們還在提交隊(duì)列中增加了自動檢查,以防止提交會破壞 Python 3 支持的改動。

通過自動測試確保沒問題之后,我們就開始將 Python 3 的改動推送給真正的用戶。我們通過遠(yuǎn)程的功能開關(guān)來將新功能逐漸開放給用戶。首先對 Dropbox 推送改動,這樣我們就能找出并改正大部分主要的底層問題。然后將范圍擴(kuò)大到 Beta 用戶,他們的 OS 版本問題更加蕪雜。然后最終擴(kuò)展到穩(wěn)定版。7 個月之后,所有的 Dropbox 都已經(jīng)在運(yùn)行 Python 3 了。為了盡可能提高質(zhì)量,我們要求所有與轉(zhuǎn)換相關(guān)的 bug 必須進(jìn)行深入調(diào)查并徹底修復(fù),才能擴(kuò)大推送的范圍。



逐漸推送到 Beta 版


逐漸推送到穩(wěn)定版

到了版本 52 時,這個過程終于完成了。我們可以完全從 Dropbox 的桌面客戶端中刪掉 Python 2 了。



寫在最后


一篇文章很難完整概括我們將代碼遷移至 Python 3.0 的完整過程,這其中還有許多可以討論的東西。接下來,我們還會在以后的文章中討論:

  • 我們怎樣在 Windows 和 macOS 上報(bào)告崩潰,并利用這些信息調(diào)試原生和 Python 代碼;
  • 怎樣維護(hù) Python 2 和 Python 3 混合代碼,用到了哪些工具?
  • 整個 Python 3 轉(zhuǎn)換過程中最值得討論的 Bug 和故事。

敬請期待,也歡迎在下方留言分享你對遷移過程的看法。

原文:https://blogs.dropbox.com/tech/2018/09/how-we-rolled-out-one-of-the-largest-python-3-migrations-ever/作者:Max Bélanger和Damien DeVille譯者:彎月,責(zé)編:屠敏

征稿啦

CSDN 公眾號秉持著「與千萬技術(shù)人共成長」理念,不僅以「極客頭條」、「暢言」欄目在第一時間以技術(shù)人的獨(dú)特視角描述技術(shù)人關(guān)心的行業(yè)焦點(diǎn)事件,更有「技術(shù)頭條」專欄,深度解讀行業(yè)內(nèi)的熱門技術(shù)與場景應(yīng)用,讓所有的開發(fā)者緊跟技術(shù)潮流,保持警醒的技術(shù)嗅覺,對行業(yè)趨勢、技術(shù)有更為全面的認(rèn)知。如果你有優(yōu)質(zhì)的文章,或是行業(yè)熱點(diǎn)事件、技術(shù)趨勢的真知灼見,或是深度的應(yīng)用實(shí)踐、場景方案等的新見解,歡迎聯(lián)系 CSDN 投稿,聯(lián)系方式:微信(guorui_1118,請備注投稿+姓名+公司職位),郵箱(guorui@csdn.net)。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python腳本如何生成Windows可執(zhí)行文件.exe | 書影博客
「python」開啟,關(guān)閉Windows進(jìn)程的簡單腳本
利用Python做一個桌面版的翻譯軟件,超容易幾十行代碼就可以搞定
用Psyco讓Python運(yùn)行得像C一樣快
保護(hù)源碼!加密你的 Python 程序代碼!
在IE中使用Python作為開發(fā)腳本
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服