Praktik terbaik untuk menyimpan file konfigurasi dengan python

Saya memiliki skrip python di mana saya memiliki file konfigurasi yang terlihat seperti ini:

PROD = 'production'
DEV = 'dev'
ENVIRONMENT = None

dan saya memiliki fungsi yang mendapatkan lingkungan yang diinginkan dari argumen perintah dan menetapkannya seperti:

if sys.argv[1] in [config.PROD, config.DEV]:
    config.ENVIRONMENT = sys.argv[1]

Saya memahami ini bukan praktik yang baik ketika saya mulai mengimpor file konfigurasi dalam banyak file dan ENV terus mengatur ulang kembali ke Tidak Ada.

Jadi, pertanyaan saya adalah: praktik terbaik apa yang ada dalam kasus ini


person Ofrine    schedule 29.11.2017    source sumber


Jawaban (1)


Saya tidak yakin apa praktik terbaiknya, tetapi saya suka menggunakan file JSON. Saya menggunakan kelas berikut sebagai lapisan abstraksi untuk berinteraksi dengan file konfigurasi (properti). Anda dapat membuat satu JSONPropertiesFile dan menyebarkannya ke aplikasi Anda.

import json
from collections import OrderedDict
import os
from stat import * # ST_SIZE etc
from datetime import datetime
from copy import deepcopy


class JSONPropertiesFileError(Exception):
    pass


class JSONPropertiesFile(object):

    def __init__(self, file_path, default={}):
        self.file_path = file_path
        self._default_properties = default
        self._validate_file_path(file_path)

    def _validate_file_path(self, file_path):
        if not file_path.endswith(".json"):
            raise JSONPropertiesFileError(f"Must be a JSON file: {file_path}")
        if not os.path.exists(file_path):
            self.set(self._default_properties)

    def set(self, properties):
        new_properties = deepcopy(self._default_properties)
        new_properties.update(properties)
        with open(self.file_path, 'w') as file:
            json.dump(new_properties, file, indent=4)


    def get(self):
        properties = deepcopy(self._default_properties)
        with open(self.file_path) as file:
            properties.update(json.load(file, object_pairs_hook=OrderedDict))
        return properties

    def get_file_info(self):
        st = os.stat(self.file_path)
        res = {
            'size':st[ST_SIZE],
            'size_str':str(round(st[ST_SIZE]/1000,2)) + ' KB',
            'last_mod': datetime.fromtimestamp(st[ST_MTIME]).strftime("%Y-%m-%d")
         }
         return res

Dalam kasus Anda, Anda mungkin menggunakannya seperti ini:

file_path = "path/to/your/config/file"
default_properties = {
    'PROD': 'production',
    'DEV': 'dev',
    'ENVIRONMENT': ""
} 
config_file = JSONPropertiesFile(file_path, default_properties)
config = config_file.get() 
print(config["PROD"])
config["PROD"] = "something else"
config_file.set(config) #  save new config
person J. Darnell    schedule 29.11.2017
comment
Terima kasih atas jawaban Anda, tetapi menurut saya solusi ini agak berlebihan dan tidak terlihat bagus. Dalam solusi saya (tidak berfungsi), untuk mengakses ENV, Anda memanggil config.ENV dan selesai. Di milik Anda, Anda harus memanggil JSONPropertiesFile.get()['ENV'], dan meskipun sangat kuat, saya yakin ini tidak bagus (dan juga memerlukan membaca/menulis dari/ke file) - person Ofrine; 30.11.2017
comment
Saya bisa memahami bahwa ini berlebihan. Dimungkinkan untuk mengubah solusi saya menjadi sesuatu yang memungkinkan Anda melakukan .ENV, meskipun itu hanya akan membuatnya lebih rumit. Apakah Anda ingin memuatnya dari sistem file satu kali dan kemudian tidak melakukan apa pun lagi dengan sistem file? - person J. Darnell; 30.11.2017