最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Python 工匠:一個關(guān)于模塊的小故事

2022-08-12 16:47 作者:騰訊藍(lán)鯨智云  | 我要投稿

前言


模塊(Module)是我們用來組織 Python 代碼的基本單位。很多功能強(qiáng)大的復(fù)雜站點(diǎn),都由成百上千個獨(dú)立模塊共同組成。

雖然模塊有著不可替代的用處,但它有時也會給我們帶來麻煩。比如,當(dāng)你接手一個新項(xiàng)目后,剛展開項(xiàng)目目錄。第一眼就看到了攀枝錯節(jié)、難以理解的模塊結(jié)構(gòu),那你肯定會想:“這項(xiàng)目也太難搞了?!?/p>

在這篇文章里,我準(zhǔn)備了一個和模塊有關(guān)的小故事與你分享。

一個關(guān)于模塊的小故事

小 R 是一個剛從學(xué)校畢業(yè)的計(jì)算機(jī)專業(yè)學(xué)生。半個月前,他面試進(jìn)了一家互聯(lián)網(wǎng)公司做 Python 開發(fā),負(fù)責(zé)一個與用戶活動積分有關(guān)的小項(xiàng)目。項(xiàng)目的主要功能是查詢站點(diǎn)活躍用戶,并為他們發(fā)送有關(guān)活動積分的通知:“親愛的用戶,您好,您當(dāng)前的活動積分為 x”。

項(xiàng)目主要由 notify_users.py 腳本和 fancy_site 包組成,結(jié)構(gòu)與各文件內(nèi)容如下:


文件 notify_users.py:


文件 fancy_site/users.py:


文件:fancy_site/marketing.py:


只要在項(xiàng)目目錄下執(zhí)行 python notify_user.py,就能實(shí)現(xiàn)給所有活躍用戶發(fā)送通知。

需求變更

但有一天,產(chǎn)品經(jīng)理找過來說,光給用戶發(fā)站內(nèi)信通知還不夠,容易被用戶忽略。除了站內(nèi)信以外,我們還需要同時給用戶推送一條短信通知。

琢磨了五秒鐘后,小 R 跟產(chǎn)品經(jīng)理說:“這個需求可以做!”。畢竟給手機(jī)號發(fā)送短信的 send_sms() 函數(shù)早就已經(jīng)有人寫好了。他只要先給 add_notification 方法添加一個可選參數(shù) enable_sms=False,當(dāng)傳值為 True 時調(diào)用 fancy_site.marketing 模塊里的 send_sms 函數(shù)就行。

一切聽上去根本沒有什么難度可言,十分鐘后,小 R 就把 user.py 改成了下面這樣:


但是,當(dāng)他修改完代碼,再次執(zhí)行 notify_users.py 腳本時,程序卻報(bào)錯了:


錯誤信息說,無法從 fancy_site.users 模塊導(dǎo)入 User 對象。

解決環(huán)形依賴問題

小 R 仔細(xì)分析了一下錯誤,發(fā)現(xiàn)錯誤是因?yàn)?users 與 marketing 模塊之間產(chǎn)生的環(huán)形依賴關(guān)系導(dǎo)致的。

當(dāng)程序在 notify_users.py 文件導(dǎo)入 fancy_site.users 模塊時, users 模塊發(fā)現(xiàn)自己需要從 marketing 模塊那里導(dǎo)入 send_sms 函數(shù)。而解釋器在加載 marketing 模塊的過程中,又反過來發(fā)現(xiàn)自己需要依賴 users 模塊里面的 User 對象。

如此一來,整個模塊依賴關(guān)系成為了環(huán)狀,程序自然也就沒法執(zhí)行下去了。


不過,沒有什么問題能夠難倒一個可以正常訪問 Google 的程序員。小 R 隨便上網(wǎng)一搜,發(fā)現(xiàn)這樣的問題很好解決。因?yàn)?Python 的 import 語句非常靈活,他只需要 把在 users 模塊內(nèi)導(dǎo)入 send_sms 函數(shù)的語句挪到 add_notification 方法內(nèi),延緩 import 語句的執(zhí)行就行啦。


改動一行代碼后,大功告成。小 R 簡單測試后,發(fā)現(xiàn)一切正常,然后把代碼推送了上去。不過小 R 還沒來得及為自己點(diǎn)個贊,意料之外的事情發(fā)生了。

這段明明幾乎完美的代碼改動在 Code Review 的時候被審計(jì)人小 C 拒絕了。

小 C 的疑問

小 R 的同事小 C 是一名有著多年經(jīng)驗(yàn)的 Python 程序員,他對小 R 說:“使用延遲 import,雖然可以馬上解決包導(dǎo)入問題。但這個小問題背后隱藏了更多的信息。比如,你有沒有想過 send_sms 函數(shù),是不是已經(jīng)不適合放在 marketing 模塊里了?”

被小 C 這么一問,聰明的小 R 馬上意識到了問題所在。要在 users 模塊內(nèi)發(fā)送短信,重點(diǎn)不在于用延遲導(dǎo)入解決環(huán)形依賴。而是要以此為契機(jī),發(fā)現(xiàn)當(dāng)前模塊間依賴關(guān)系的不合理,拆分/合并模塊,創(chuàng)建新的分層與抽象,最終消除環(huán)形依賴。

認(rèn)識清楚問題后,他很快提交了新的代碼修改。在新代碼中,他創(chuàng)建了一個專門負(fù)責(zé)通知與消息類的工具模塊 msg_utils,然后把 send_sms 函數(shù)挪到了里面。之后 users 模塊內(nèi)就可以毫無困難的從 msg_utils 模塊中導(dǎo)入 send_sms 函數(shù)了


新的模塊依賴關(guān)系如下圖所示:


在新的模塊結(jié)構(gòu)中,整個項(xiàng)目被整齊的分為三層,模塊間的依賴關(guān)系也變得只有單向流動。之前在函數(shù)內(nèi)部 import 的“延遲導(dǎo)入”技巧,自然也就沒有用武之地了。

小 R 修改后的代碼獲得了大家的認(rèn)可,很快就被合并到了主分支。故事暫告一段落,那么這個故事告訴了我們什么道理呢?

總結(jié)

模塊間的循環(huán)依賴是一個在大型 Python 項(xiàng)目中很常見的問題,越復(fù)雜的項(xiàng)目越容易碰到這個問題。當(dāng)我們在參與這些項(xiàng)目時,如果對模塊結(jié)構(gòu)、分層、抽象缺少應(yīng)有的重視。那么項(xiàng)目很容易就會慢慢變得復(fù)雜無比、難以維護(hù)。

所以,合理的模塊結(jié)構(gòu)與分層非常重要。它可以大大降低開發(fā)人員的心智負(fù)擔(dān)和項(xiàng)目維護(hù)成本。這也是我為什么要和你分享這個簡單故事的原因?!霸诤瘮?shù)內(nèi)延遲 import” 的做法當(dāng)然沒有錯,但我們更應(yīng)該關(guān)注的是:整個項(xiàng)目內(nèi)的模塊依賴關(guān)系與分層是否合理。

最后,讓我們再嘗試從 小 R 的故事里強(qiáng)行總結(jié)出幾個道理吧:

  • 合理的模塊結(jié)構(gòu)與分層可以降低項(xiàng)目的開發(fā)維護(hù)成本

  • 合理的模塊結(jié)構(gòu)不是一成不變的,應(yīng)該隨著項(xiàng)目發(fā)展調(diào)整

  • 遇到問題時,不要選“簡單但有缺陷”的那個方案,要選“麻煩但正確”的那個

  • 整個項(xiàng)目內(nèi)的模塊間依賴關(guān)系流向,應(yīng)該是單向的,不能有環(huán)形依賴存在

附錄

  • 題圖來源: Photo by Ricardo Gomez Angel on Unsplash

  • 更多系列文章地址:https://github.com/piglei/one-python-craftsman

系列其他文章:

Python 工匠:讓函數(shù)返回結(jié)果的技巧

http://mp.weixin.qq.com/s?__biz=Mzg2NjExNDI0MQ==&mid=2247483658&idx=1&sn=ac7222c597c2c063fab225af818a84af&chksm=ce4e8ea4f93907b2267ea873fd57b4a1c9cd640ee03d84f88672e0749472f91bbceb712083ce&scene=21#wechat_redirect

Python 工匠:異常處理的三個好習(xí)慣

http://mp.weixin.qq.com/s?__biz=Mzg2NjExNDI0MQ==&mid=2247483664&idx=1&sn=0897d215ab2fc80399397d6f982f9f04&chksm=ce4e8ebef93907a80c31b79acc3d73e5a741ccd412ba6e6741cf0f5ed9e342b5878acbb754d3&scene=21#wechat_redirect

Python 工匠:編寫地道循環(huán)的兩個建議

http://mp.weixin.qq.com/s?__biz=Mzg2NjExNDI0MQ==&mid=2247483669&idx=1&sn=f1fde152bfc7a8a606967b18824f42dc&chksm=ce4e8ebbf93907adabff31678bbf92d3a47c4708cd6b1a232dc74064005a6118b775867fc008&scene=21#wechat_redirect

藍(lán)鯨智云

本文由騰訊藍(lán)鯨智云編輯發(fā)布,騰訊藍(lán)鯨智云(簡稱藍(lán)鯨)軟件體系是一套基于PaaS的技術(shù)解決方案,致力于打造行業(yè)領(lǐng)先的一站式自動化運(yùn)維平臺。目前已經(jīng)推出社區(qū)版、企業(yè)版,歡迎體驗(yàn)。

  • 官網(wǎng):https://bk.tencent.com/

  • 下載鏈接:https://bk.tencent.com/download/

  • 社區(qū):https://bk.tencent.com/s-mart/community/question


Python 工匠:一個關(guān)于模塊的小故事的評論 (共 條)

分享到微博請遵守國家法律
铅山县| 湖北省| 新泰市| 巴林右旗| 黄石市| 临海市| 潼关县| 通山县| 苏州市| 永德县| 民县| 阳泉市| 新疆| 合作市| 海原县| 萨迦县| 察雅县| 石狮市| 永顺县| 齐齐哈尔市| 塔城市| 礼泉县| 禹州市| 辰溪县| 霸州市| 济宁市| 卢龙县| 孟村| 富源县| 监利县| 罗定市| 久治县| 祁门县| 正定县| 苏尼特右旗| 桃园县| 卓资县| 卢龙县| 达拉特旗| 黑山县| 浏阳市|