본문 바로가기

Python

간단한 설정파일을 직접 만들어서 사용해보자

프로그램을 만들다보면 설정파일이 있으면 편하겠다는 생각을 종종 한다. 

예를 들어, 서버IP를 코드에 직접 넣는 것은 왠지... 이건 아닌데.. 라는 생각이 들 때라던가, 사용자 이름 또는 각종 실험적인 기능의 on/off 를 매번 코드에서 조절하기 힘들기도 하고, 실행시 파라미터로 받는 것도 귀찮을 때가 있다.

 

그럴때는 간단히 나만의 설정파일을 만들어놓고, 그 설정파일을 읽어서 처리하면 종종 쉽게 처리된다.

 

그런데 설정파일을 간단히 작성한다고 해도, 각 설정마다 comment도 넣어서 알기 쉽게 만들고 싶기도 하다.

그러다가 점점 일이 커지면... 그냥 코드에 적어 넣게 된다. 죄 짓는 느낌과 함께...

 

먼저 아래처럼 간단한 설정파일을 만들었다. 

key = value 의 형태를 가지고 있고, # 이 나오면 그 이후는 comment로 생각하기로 했다. 

# comment
# key = value

###################
# owner info
pc_owner = james	# james lala
local_ip = 192.168.0.10

####################
# ip setting
server_ip = 192.168.0.100	# always on
client_ip = 192.168.0.20	

####################
# working jobs
auto_firewall = 1		# 0:off, 1:on
dns_host = always
max_retry_cnt = 30
response_interval = 1.5		# hour

log_path = /mnt/mount/log

이 파일을 읽어서 설정에 따라 프로그램이 동작하도록 해보자. 

 

역시 파싱하기 귀찮으니 쳇지피티에게 물어보자. 

귀찮으니 쳇지피티에게 물어보자

아래와 같은 코드를 만들어주었다. 

def parse_settings(file_path):
    settings = {}

    with open(file_path, "r", encoding="utf-8") as file:
        for line in file:
            line = line.strip()
            if not line or line.startswith("#"):  # 빈 줄 또는 주석 무시
                continue

            if "=" in line:
                key, value = line.split("=", 1)  # 첫 번째 `=` 기준으로 나누기
                key = key.strip()
                value = value.split("#")[0].strip()  # 주석 제거
                settings[key] = value

    return settings


# 파일 경로 지정 후 실행
file_path = "/mnt/data/setting.txt"
parsed_settings = parse_settings(file_path)
print(parsed_settings)

 

약간 의심의 눈초리로... 직접 실행을 시켜보자. 

쳇지피티가 알려준 결과와 직접 실행해본 결과가 같다.

 

오, 별 문제없이 실행되었다. 

오늘은 여기서 끝...

... 이면 좀 아쉬우니 코드를 좀 더 보자. 

 

핵심부분은 아래와 같다. 

        for line in file:
            line = line.strip()
            if not line or line.startswith("#"):  # 빈 줄 또는 주석 무시
                continue

            if "=" in line:
                key, value = line.split("=", 1)  # 첫 번째 `=` 기준으로 나누기
                key = key.strip()
                value = value.split("#")[0].strip()  # 주석 제거
                settings[key] = value

파일에서 라인을 읽어서

    line.strip()을 통해서 해당 라인의 앞뒤 공백을 제거하고 

    라인 안에 "=" 가 있으면

        line.split("=", 1) 을 통해서 첫번째 "="를 기준으로 라인을 key, value로 나누고

        key.strip() 으로 key 앞뒤의 공백을 제거하고

        value = value.split("#")[0].strip() 으로 "#"을 기준으로 앞,뒤로 나누고 앞의 값을 가져와서 strip()으로 공백을 제거함.

        마지막으로 settings[key] = value로 dictionary를 만든다. 

 

split()과 strip()을 잘 써서 쉽게 구현한 것을 볼 수 있다. 

 

한발 더 나아가서 타입변환도 요청해보자. 

타입변환도 해줘. 넵.

def parse_settings(file_path):
    settings = {}

    def convert_value(value):
        """값을 적절한 타입(int, float, str)으로 변환"""
        if value.isdigit():  # 정수 변환
            return int(value)
        try:
            return float(value)  # 실수 변환
        except ValueError:
            return value  # 변환 불가하면 문자열 그대로 반환

    with open(file_path, "r", encoding="utf-8") as file:
        for line in file:
            line = line.strip()
            if not line or line.startswith("#"):  # 빈 줄 또는 주석 무시
                continue

            if "=" in line:
                key, value = line.split("=", 1)  # 첫 번째 `=` 기준으로 나누기
                key = key.strip()
                value = value.split("#")[0].strip()  # 주석 제거
                settings[key] = convert_value(value)

    return settings


# 파일 경로 지정 후 실행
file_path = "/mnt/data/setting.txt"
parsed_settings = parse_settings(file_path)
print(parsed_settings)

 

타입변환까지 요청하니 convert_value() 함수를 하나 더 추가해줬다. 

자세히 보니 isdigit() 을 이용해서 정수를 판별하고, 안되면 실수로 변환하는데, 이때 에러가 나면 모두 string으로 판단하는 로직이다. 

깔끔하게 잘 만든 것 같다. 

 

실행결과는 아래와 같다고 한다. 

실행결과도 예쁘게 보여주는 군

 

내가 동작시켰을 때도 동일한 결과가 나왔다. 

나는 안예쁘게 나오는데?? 하지만 내용물은 같다.

 

오늘 예제로 세팅파일을 쉽게 만들고, 쉽게 활용할 수 있으면 한다. 

 

오늘은 여기까지.