2017-09-23 90 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文件或者在運行時更改某些配置時寫入它,我基本上就會寫入全局。這不是一個壞習慣嗎(因爲寫入全球通常被認爲是不好的做法)? –