db2 参数标识符使用无效_在Python应用程序中使用配置的最佳实践
介紹除了最簡單的程序外,所有的程序都有一組參數來控制它們的行為。作為具體的例子,考慮ls工具的輸出格式、nginx監聽的端口或git在提交消息中使用的電子郵件地址。根據應用程序的大小和復雜性,可能有許多這樣的參數,它們可能只影響一個小的執行細節或者整個程序行為。當您處理配置時,有很多方面需要考慮:首先,它是如何從外部傳遞到您的程序中的,如何解析和驗證?其次,如何在程序內部處理、訪問和在組件之間傳遞?根據應用程序的類型,您必須考慮在程序運行時用戶如何檢查和更新它。從操作的角度來看,您可能必須考慮如何管理、測試多個配置并將其部署到生產環境中。每一個主題都可能變得相當復雜,值得深入探討。不過,在這篇博文中,我只想關注第二個方面。我將介紹一些處理程序內部配置的指導原則,這些原則是經過時間檢驗的,我想推薦給任何開發中小型應用程序的人。在過去,我用各種編程語言(如Go、Scala和Python)構建和維護應用程序。在這篇博文中,我想以Python為例,因為它的動態特性允許使用很多機制用以提高開發速度和靈活性(例如,在運行時修改類),但從長遠來看可能會使維護和重構更加困難。一個簡單的例子當談到軟件應該如何工作以及組件應該如何交互的重要思想時,有時很難與實際編碼聯系起來。為了避免出現這種情況,讓我們跳到下面的代碼示例中,看看我想在本文中解決的一些問題:在評論中,我已經給出了一些關于該代碼可能存在的缺點,但是讓我們現在更詳細地探討一下。指導原則編程是一項在智力上具有挑戰性的任務,因此我認為作為軟件工程師,我們應該將盡可能多的復雜任務委托給我們的工具,如ide、linter、格式化程序、編譯器或類型檢查程序。如果可以使用一個工具來發現錯誤和提高代碼質量,那么我認為這就證明了用這種工具來編寫代碼是合理的。另外,如果盡管我們仔細檢查和使用了工具,但代碼中仍有錯誤,那么應該在應用程序啟動時盡快報告,這會產生一個重要的警告消息,并且在許多情況下,程序會立即退出。最糟糕的事情莫過于在一次看似成功的部署的幾個小時后,半夜里發現某個配置密鑰丟失。基于這些基礎,我認為處理應用程序內部配置的數據結構應該遵循以下四個原則:
它應該使用標識符而不是字符串鍵來訪問配置值。
它的值應該是靜態類型的。
應該盡早驗證。
它應該聲明在它使用的地方。
讓我在下面解釋這些原則及其作用。一.使用標識符而不是字符串鍵值可能與近年來文件交換和序列化格式的某種“JSONification”有關,以PEP 484為標準的字符串鍵詞典Dict[str,Any]似乎已經成為許多Python開發人員的一站式數據結構。很簡單,只需使用json.loads()處理一個json格式的字符串后放入Python字典,然后使用像config[“port”]或config[“user”][“email”]一樣的代碼隨意訪問它,就像我在介紹性示例中所做的那樣。(這種方法不是Python獨有的,例如Scala的Lightbend配置庫也有一個類似conf.getInt(“foo.bar”)的API。)如果需要新的配置條目,只需將其添加到JSON文件中,并在整個代碼中立即使用它。但是,這種方法有許多缺點:
無法檢測不一致的拼寫,例如,密鑰是“user”還是“users”。
如果存在不一致,不能明確哪里發生了錯誤。
只有和字典中的值相同才是正確的。
在實際訪問數據之前,不會發現丟失的數據。
無法使用IDE/工具來重命名密鑰,需要找到并替換字符串的所有匹配項。
不能使用檢查變量名格式一致性的工具。
重復的字符串解析和字典查找相當費力。
在編譯語言中,編譯器顯然會立即告訴您是否存在拼寫錯誤,但對于Python,一個足夠現代的IDE通常會指出是否使用了未聲明的變量或類成員。
類中定義中的名稱才是唯一確定的正確名稱。
即使在Python中,聲明的變量也可能沒有初始化(參見PEP 526),但在許多情況下,IDE或linter會告訴您這一點。
使用IDE可以輕松完成重命名。
可以應用普通格式化程序或樣式檢查程序。
三.早期驗證
對于大多數配置值,擁有一個特定的格式、類型或數據范圍才是有意義的。如前一節所述使用靜態類型已經是限定值必須要有某種格式的示例。可能還有其他約束,如最小值和最大值,與某個正則表達式匹配,或指向配置的另一個(已存在)部分。一種簡單的方法是在使用配置的位置執行驗證。例如,你可以寫在使用這些值時也類似。
然而,這會導致一些問題:
必須在使用該值的每個位置驗證該值,從而導致代碼重復。或者,您在使用它時需要記住是否已經驗證了它。
如果有問題,那么只有在第一次訪問配置值時才會出現問題。這使得發現錯誤更加困難,并且需要更多的力氣來檢查新的配置值是否實際有效。
如上所述,在Python中,即使在類聲明中聲明port:int,config.port在運行時也可以是一個字符串。你絕對不想在每次使用該值時都去檢查。
因此,我建議在程序啟動后盡快驗證配置,如果發現配置無效,請立即退出。注意,如果您選擇使用上一節中建議的適當類型來表示配置條目,那么在許多情況下,只要能成功地解析配置就能保證配置有效(參見解析,不要驗證)。
在操作方面,早期驗證確保程序在啟動后的一段時間內不會因為配置無效而退出。從開發的角度看,它使工作變得更容易,因為您可以在任何地方假設配置數據只包含有效值,并且可以像使用程序中的任何其他對象一樣安全地使用配置。四.在使用配置的地方聲明它最后一個原則是,配置項應該聲明在它們使用的地方附近,例如,作為使用它的代碼所在模塊中的一個類。此規則不能直接從上述基礎派生,因為它不一定有助于更有效地使用工具,也不一定有助于及早預防或報告錯誤。但是,與在一個地方聲明所有配置條目相比,它在軟件工程方面有兩個優點:物理封閉性有助于導航,例如,更容易找到使用某個配置項的位置。此外,如果您使用的數據結構還定義了配置值的有效邊界,那么在接近依賴這些邊界的代碼旁定義配置是有意義的。它有助于避免在不同的、不相關的組件中使用相同的配置項。假設您有一個條目,例如timeout,它定義在一個公共位置,并且可以從所有模塊訪問,那么很容易會去在不同的不相關位置重用同一個timeout條目,而不是添加一個新條目并適當地命名和記錄它。和在模塊中本地定義配置對比下,則更容易看出這樣做不好,例如,您很可能不會在db.backend模塊中導入web.http.config.client.timeout以將其用作數據庫連接池的設置。在測試以配置為參數的組件時,只需要為組件使用的條目創建模擬配置對象,而不需要為整個應用程序模擬完整的配置。每個模塊的子配置可以通過組合或繼承組裝成一個更大的類。一般來說,我建議組合,因為從多個小配置類繼承可能在某個點上導致命名沖突。
把碎片拼在一起所以讓我們看看如何將這些原則組合成一個小的代碼示例。這個例子深受Alexandru Nedelcu的Scala最佳實踐集合第3.5節所述方法的啟發。我們有三個模塊,每個模塊都定義了類型良好的配置類。(為了簡潔起見,我省略了import語句。)例如,app.user模塊中的類可以在構造函數中獲取其本地配置類的實例并使用它,而不必擔心類型不匹配或缺少值。用戶模塊中的單元測試不必模擬整個應用程序配置。注意,數據類特別適合這個應用程序,因為它們不能聲明成員而不初始化,這與普通的Python類相反。如果在dataclass聲明中添加了一個成員,那么mypy將報告代碼中在沒有為新成員提供值的情況下構造實例的所有位置。然后,位于不同模塊中的主程序可以定義一個應用程序范圍的配置類,如下所示:到目前為止,我還沒有討論如何實際創建實例并對這個全局配置類執行驗證。對于類似這樣的簡單情況,將字典轉換為數據類的dacite庫非常有用。請考慮以下代碼:如果執行此代碼時沒有異常,那么我們就有了一個有效的配置對象,如?我希望可以和您達成共識,上述都是傳遞配置數據的更好方法,而不僅僅是一個包含已解析的JSON內容的字典。英文原文:https://tech.preferred.jp/en/blog/working-with-configuration-in-python/ 譯者:阿布銩 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的db2 参数标识符使用无效_在Python应用程序中使用配置的最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画海绵宝宝_脑洞大开的万圣节
- 下一篇: adc采样时间_ADC采样原理