停止使用非版本控制的可执行代码

2023-01-31 00:01:54 版本 可执行 停止使用
  • local_settings这种反模式
  • 它在我的笔记本上运行良好!
  • 但是我不会犯这种错误!
  • 如何处理环境特有变量

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,发现的时候已经太晚了。

下面是一个真实的例子,来自于去年我帮客户解决的问题:

  1. 项目使用第三方库做slug。配置放在settings中。
  2. 开发者决定自己编写slug项目。在本地运行良好。
  3. 测试没有加入新的testcase,测试那些边角案例。
  4. 在本地开发环境,staging环境,甚至生产环境都看起来运行正常。
  5. 几天之后,一些特定地区的用户报告说,一些记录不可以访问。
  6. 没人知道为什么生产环境会出现这个问题。

然后我介入了。首先我就注意到,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')

相关文章