แนวปฏิบัติที่ดีที่สุดในการเก็บไฟล์ปรับแต่งใน python

ฉันมีสคริปต์ python ซึ่งฉันมีไฟล์ปรับแต่งซึ่งมีลักษณะดังนี้:

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

และฉันมีฟังก์ชันที่รับสภาพแวดล้อมที่ต้องการจากอาร์กิวเมนต์คำสั่งและตั้งค่าเป็น:

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

ฉันเข้าใจว่านั่นไม่ใช่แนวปฏิบัติที่ดีเมื่อฉันเริ่มนำเข้าไฟล์กำหนดค่าในหลายไฟล์ และ ENV ก็รีเซ็ตกลับเป็นไม่มีต่อไป

ดังนั้น คำถามของฉันคือ แนวทางปฏิบัติที่ดีที่สุดในกรณีนี้คืออะไร


person Ofrine    schedule 29.11.2017    source แหล่งที่มา


คำตอบ (1)


ฉันไม่แน่ใจว่าแนวทางปฏิบัติที่ดีที่สุดคืออะไร แต่ฉันชอบใช้ไฟล์ JSON ฉันใช้คลาสต่อไปนี้เป็นเลเยอร์ของสิ่งที่เป็นนามธรรมสำหรับการเชื่อมต่อกับไฟล์ปรับแต่ง (คุณสมบัติ) คุณสามารถสร้าง JSONPropertiesFile หนึ่งไฟล์แล้วส่งต่อไปทั่วแอปพลิเคชันของคุณ

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

ในกรณีของคุณคุณอาจใช้สิ่งนี้:

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
ขอบคุณสำหรับคำตอบของคุณ แต่ฉันคิดว่าวิธีแก้ปัญหานี้ดูเกินกำลังไปหน่อยและจะดูไม่ดีเลย ในโซลูชันของฉัน (ไม่ทำงาน) เพื่อเข้าถึง ENV คุณเรียก config.ENV เท่านี้ก็เสร็จแล้ว ในตัวคุณ คุณต้องเรียก JSONPropertiesFile.get()['ENV'] และถึงแม้ว่ามันจะแข็งแกร่งมาก แต่ฉันเชื่อว่ามันไม่สวย (และต้องอ่าน/เขียนจาก/ไปยังไฟล์ด้วย) - person Ofrine; 30.11.2017
comment
ฉันเข้าใจได้ว่าสิ่งนี้เกินกำลัง เป็นไปได้ที่จะเปลี่ยนโซลูชันของฉันเป็นสิ่งที่จะช่วยให้คุณทำ .ENV ได้ แม้ว่านั่นจะทำให้ซับซ้อนมากขึ้นก็ตาม คุณต้องการที่จะโหลดมันจากระบบไฟล์เพียงครั้งเดียวและไม่ต้องทำอะไรกับระบบไฟล์อีกต่อไปหรือไม่? - person J. Darnell; 30.11.2017