.INI 파일에 설정을 읽고 쓰는 것을 간편하게 하기 위한 boilerplate(부뚜막?) 코드



개요


다음 의식의 흐름에 의해 처리된다.

  1. 소스 상의 디폴트 설정값을 적용한다.
  2. .INI 파일이 존재할 경우 .INI 파일 상의 설정값을 적용한다.
  3. 최종 설정값을 .INI 파일에 저장한다.


소스


easyconfig.py
# -*- coding: utf-8 -*-
#!/usr/bin/python

import configparser

class EasyConfig:

    SECTION_DEFAULT = 'DEFAULT'
    configFileName = None

    # 설정 파일명을 세팅함
    def setFileName(self, fileName):
        self.configFileName = fileName

    # 파일로부터 설정을 세팅함
    def loadConfig(self, configParam):
        if not self.configFileName:
            return
        
        configFile = configparser.ConfigParser()
        configFile.read(self.configFileName)
        
        for key in configParam.keys():
            if key in configFile[self.SECTION_DEFAULT]:
                if type(configParam[key]) == int:
                    try:
                        val = int(configFile[self.SECTION_DEFAULT][key])
                        configParam[key] = val
                    except:
                        pass
                elif type(configParam[key]) == float:
                    try:
                        val = float(configFile[self.SECTION_DEFAULT][key])
                        configParam[key] = val
                    except:
                        pass
                elif type(configParam[key]) == bool:
                    if configFile[self.SECTION_DEFAULT][key] == 'True':
                        configParam[key] = True
                    else:
                        configParam[key] = False
                else:
                    configParam[key] = configFile[self.SECTION_DEFAULT][key]

    # 현재 설정을 파일로 저장함
    def saveConfig(self, configParam):
        if not self.configFileName:
            return
        
        configFile = configparser.ConfigParser()
        
        for key in configParam:
            val = None
            if type(configParam[key]) == int:
                val = "%d" % configParam[key]
            elif type(configParam[key]) == float:
                val = "%f" % configParam[key]
            elif type(configParam[key]) == bool:
                if configParam[key]:
                    val = 'True'
                else:
                    val = 'False'
            elif type(configParam[key]) == str:
                val = configParam[key]

            if val:
                configFile[self.SECTION_DEFAULT][key] = val
        
        with open(self.configFileName, 'w') as writeFile:
            configFile.write(writeFile)

    # 현재 설정 내용을 출력함
    def dumpConfig(self, configParam):
        for key in configParam:
            if type(configParam[key]) == int:
                print("%s = %d[int]" % (key, configParam[key]))
            elif type(configParam[key]) == float:
                print("%s = %f[float]" % (key, configParam[key]))
            elif type(configParam[key]) == bool:
                if configParam[key]:
                    print("%s = True[bool]" % key)
                else:
                    print("%s = False[bool]" % key)
            elif type(configParam[key]) == str:
                print("%s = %s[str]" % (key, configParam[key]))

    def process(self, configParam):
        self.loadConfig(configParam)
        self.saveConfig(configParam)

  • DEFAULT 섹션만을 사용한다. 그 외의 섹션을 사용하려면 섹션 존재 여부를 확인하는 추가적인 처리가 필요하다.


사용 방법


client.py
from easyconfig import *

# 설정 디폴트 값을 맵으로 정의한다
configDef = {}
configDef["A"] = "B"
configDef["C"] = "D"
configDef["E"] = 12
configDef["F"] = 3.14
configDef["G"] = True

easyConfig = EasyConfig()
easyConfig.setFileName('ec_config.ini') # 설정 파일명을 정의한다
easyConfig.process(configDef) # 설정 파일을 처리한다

  • int, float, bool, 문자열 타입만 지원한다. 설정 맵 상에 그 외의 타입이 존재할 경우 저장은 되지 않는다.


참고사항

<테스트 환경>
- OS : Windows 10
- Python 버전 : 3.7.5
,

표준 라이브러리인 configparser를 사용하면 .INI 파일을 읽고 쓸 수 있다.



.INI 파일 쓰기

import configparser

config = configparser.ConfigParser()
config['AAA'] = {}                # 섹션을 생성한다
config['AAA']['BBB'] = 'CCC'      # 섹션 아래 실제 값을 생성한다
config['DEFAULT']['DDD'] = 'EEE'      # DEFAULT 섹션은 기본적으로 생성되어 있어 생성없이 쓸 수 있다

with open('config.ini', 'w') as configfile:
    config.write(configfile)

  • 1 Depth에 반드시 섹션을 생성한 후에 그 아래 값을 생성할 수 있다. (1 Depth에는 값을 생성할 수 없다)
  • Depth는 최대 2 Depth까지 가능하다. (2 Depth에는 섹션을 생성할 수 없다)


.INI 파일 읽기 (기본)

import configparser

config = configparser.ConfigParser()
config.read('config.ini')

print("config['AAA']['BBB'] : " + config['AAA']['BBB'])


.INI 파일 읽기 (고급)

import configparser

config = configparser.ConfigParser()
config.read('config.ini')

if not 'AAA' in config:           # 섹션이 존재하는지 체크
    print("config['AAA'] not exist")
   
if 'BBB' in config['AAA']:        # 섹션 아래 값이 존재하는지 체크
    print("config['AAA']['BBB'] : " + config['AAA']['BBB'])
else:
    print("config['AAA']['BBB'] not exist")
    
if 'DDD' in config['AAA']:        # 섹션 아래 값이 존재하는지 체크
    print("config['AAA']['DDD'] : " + config['AAA']['DDD'])
else:
    print("config['AAA']['DDD'] not exist")

  • Config 파일이 존재하지 않을 경우는, 에러가 나지 않고 단지 빈 맵으로 반환된다.(DEFAULT 섹션은 존재한다)


참고사항

<테스트 환경>
 - OS : Windows 10
 - Python 버전 : 3.7.5
,