開發世界現在有很多反設計模式的開發方式,比如使用可執行代碼文件作為配置文件。 ...
https://www.pydanny.com/using-executable-code-outside-version-control.html
開發世界現在有很多反設計模式的開發方式,比如使用可執行代碼作為配置文件。
在Python世界裡面,你很可能碰到過類似下麵的代碼:
# 警告:這是反模式代碼!
try:
from .local_settings import *
except ImportError:
pass
一般來說,人們會在local_settings.py
文件中加入一些配置變數,然後加入到.gitignore
裡面。因此,本地開發環境,你的項目需要一個脫離版本控制的可執行代碼文件。
如果你覺得不對勁,那麼你走在正確的道路上。可執行代碼就應該總是處於版本控制中。
另一個更好的方式是,把secrets和key等配置放在環境變數裡面。如果你不喜歡這種方式,或者因為環境的原因不可以這麼做,仍然可以把配置放在JSON, YAML, TOML文件裡面。
local_settings
這種反模式
說local_settings
是反模式,是因為你生產環境的可執行代碼,不能被開發者看到,也讓他們不好debug解決問題。可能你還沒有這種體驗,但這確實是最糟糕的調試噩夢之一。
它在我的筆記本上運行良好!
有時候,在開發和測試中沒有發現一些細微的bug,發現的時候已經太晚了。
下麵是一個真實的例子,來自於去年我幫客戶解決的問題:
- 項目使用第三方庫做slug。配置放在settings中。
- 開發者決定自己編寫slug項目。在本地運行良好。
- 測試沒有加入新的testcase,測試那些邊角案例。
- 在本地開發環境,staging環境,甚至生產環境都看起來運行正常。
- 幾天之後,一些特定地區的用戶報告說,一些記錄不可以訪問。
- 沒人知道為什麼生產環境會出現這個問題。
然後我介入了。首先我就註意到,settings文件裡面有下麵這種代碼:
# 警告:這是反模式代碼!
try:
from .local_settings import *
except ImportError:
pass
他們在版本控制之外還有可執行代碼。這也是為什麼在開發環境有效,但是在其它環境有問題。即使這個微妙的bug,已經通過了常規的測試。但是,進入生產環境之後,這個bug就會被用戶發現。
然後,最糟糕的是,這個bug在第一時間幾乎不可能被髮現,因為開發者的local_settings.py
的值是正確的。
但是我不會犯這種錯誤!
人們一般會氣憤地說,“我不像你那麼蠢,我不會犯這種錯誤。“
是的,最近20年我也只碰到去年這一次因為這個原因造成的bug。
但是我相信,不管程式員都沒天才,多麼有經驗,都無可避免會犯一些愚蠢的錯誤。這是為什麼一些好的程式員/工程師都會遵循一個很好的習慣 -- 在犯了愚蠢錯誤的時候,能夠快速捕獲。如果你認為自己能夠完全避免這種錯誤,我只能說你太年輕了。
回到正題,為什麼一定要把配置放在可執行文件里?你可以將它們放在環境變數,或者配置文件。所以,爭論結束!
如何處理環境特有變數
使用環境變數,或者配置文件!
你可以使用第三方庫。我個人喜歡使用django中自帶的功能.
import os
from django.core.exceptions import ImproperlyConfigured
def get_env_var(var_name):
try:
return os.environ[var_name]
except KeyError:
error_msg = f"Set the {var_name} environment variable"
return ImproperlyConfigured(error_msg)
SECRET_KEY = get_env_var('SECRET_KEY')