2017-09-23 91 views
0

我正在编写需要打开JSON文件的代码,该文件包含与使用该软件相关的常规配置,将其解析为字典并可能覆盖其某些值。在运行期间需要多次访问这些配置以检查设置。用于处理配置文件的设计

例如:其中一个配置是“用户名”和“密码”,如果用户不存在或需要读取其他信息,则需要由用户填写。另一个配置涉及“软件应该如何工作”,具有“模式A”,“模式B”和“模式C”的可能值。

问题是:我不是程序员,我也搞不清楚管理配置的好设计。我应该打开JSON文件,每次需要时重写并保存它,或者将其解析为一个变量并将此变量保存在内存中,直到我不再需要它为止(在代码运行之前),然后将其保存到最后的JSON文件?

另一个问题是:如果我更喜欢将它解析为一个变量并保存它直到程序结束,我应该怎么做?这个变量需要被几个函数访问,所以我认为我应该使用一个全局变量,但是我已经读过使用“全局”语句写入全局变量是一个不好的做法,可能会导致一团糟。例如:

import json 
config_global = None 

def read_JSON_file(): 
    config_file = open(r'config_file.json') 
    global config_global 
    config_global = json.load(config_file) 
    config_file.close() 

def functionA(): 
    global config_global 
    # Do something with config_global 

def functionB(): 
    global config_global 
    # Do something with config_global 

def save_JSON_file() 
    config_file = open(r'config_file.json', 'w') 
    json.dump(config_global, config_file) 
    config_file.close() 

read_JSON_file() 
functionA() 
functionB() 
save_JSON_file() 

我还以为我可以通过函数调用之间的配置变量的引用,但我不知道这是否会是一个很好的解决方案,因为我将不得不通过它为每功能,每次:

import json 

def read_JSON_file() -> dict: 
    config_file = open(r'config_file.json') 
    config = json.load(config_file) 
    config_file.close() 
    return config 

def functionA(config: dict): 
    # Do something with config 

def functionB(config: dict): 
    # Do something with config 

def save_JSON_file(config: dict) 
    config_file = open(r'config_file.json', 'w') 
    json.dump(config, config_file) 
    config_file.close() 

parsed_config = read_JSON_file() 
functionA(parsed_config) 
functionB(parsed_config) 
save_JSON_file(parsed_config) 

我也看到了有关使用一个单独的,我不完全了解它是如何工作的,或者这将是一个很好的解决方案的东西。

最终,我想知道这将是一个很好的解决方案。请告诉我可能遇到的问题,我可能会遇到我的实施,并免费提出更好的解决方案。

感谢您的关注和帮助。

+0

我是一名程序员,我无法弄清楚管理配置的好设计。 – evilSnobu

回答

0

我会使配置成为一个模块,它可以整个或部分地编辑在任何其他需要它的脚本中。模块基本上是单例,并且在第一次加载时缓存在sys.modules中,并且如果随后尝试重新使用它,则会使用该条目 - 因此它不会导致每次发生实际读取和执行的开销。

在配置模块的主体中​​,您可以打开并加载json文件中的信息。此信息可以通过多种方式提供。一个是简单的字典(可能只是任何json.load()返回,另一个会解析并转换它,并创建与其各个部分相对应的模块属性。)

当然,您也可以添加您希望模块的任何功能。例如,你可能需要一个特殊的函数,它必须在它包含的值被调用之前被调用,而不是在第一次导入时自动执行它。

换句话说,这将是一个非常灵活的方法来处理问题,允许大量定制,因为它是可扩展的。

+0

好的,所以我会有一个新的模块,其中包含一个名为“config_global”的全局变量,它将具有由json.load()返回的字典的值,对吗?然后,当我需要访问配置时,我会导入这个新模块并获取它的“config_global”变量。但是,如果我需要覆盖config_global变量中的配置,我是不是正在写一个全局(即使它在其他模块内)? –

+0

假设您命名模块“config.py”,并且它定义了一个名为“config_global”的模块级变量(通过读取json文件填充),您可以从config import config_global中获取该变量。如果你改变了'config_global'的内容,它们将保留在内存中,并被任何其他具有(或将要)“导入”它的脚本看到。您可以向模块添加一个函数,将当前内容写回到原始文件或其他文件中 - 这取决于您将如何使用它来工作,因为您可以定义API以与您一起使用它觉得合适。 – martineau

+0

好吧,我明白了,这似乎是一个很好的解决方案,但我仍然有一个问题:在“config.py”模块中,“config_global”是一个全局(模块级别)变量。所以,如果我在第一次填充它时读取json文件或者在运行时更改某些配置时写入它,我基本上就会写入全局。这不是一个坏习惯吗(因为写入全球通常被认为是不好的做法)? –