Skip to main content
3 of 4
changing code thanks to comments, step1
nrp
  • 133
  • 1
  • 5

Using a class for reading config from files

The goal of my current piece of work is to read from a global config file all the settings and then from the local file only those settings that a user has chosen.

Firstly I wrote a function but then I needed a class. It's my first working class in Python, and I ask if you can kindly note its defects. Although it works, I think it can for sure be written more correctly and concisely.

Here's all the beginning:

# files to be read from
cmd_parameter = "config_1.cfg"
cmd_parameter_global = "global.cfg"

if len(sys.argv) == 2:
    cmd_parameter = sys.argv[1]
else:
    print("Error: there should be one argument after program name - config file name")
    exit(-1)

config_file = []
config_file_global = []

# reading user's config file
try:
    with open(cmd_parameter, 'r') as config_file_name:
        config_file = config_file_name.readlines()
except FileNotFoundError:
    print("File '", sys.argv[1], "' not exists or not available")
    exit(-1)

# reading global config file
try:
    with open(cmd_parameter_global, 'r') as config_file_global_name:
        config_file_global = config_file_global_name.readlines()
except FileNotFoundError:
    print("Global configuration file '", cmd_parameter_global, "' not exists or not available")
    exit(-1)

# parsing config file, reading values from it to list and matching parameters with a given argument
# parameters in config file should start with <conf_key_split1>, value should be separated from parameter by <conf_key_split2>
config_param_user = []
config_value_user = []
config_param_global = []
config_value_global = []
config = ""
conf_key_split1 = '.'
conf_key_split2 = '='
conf_key_split3 = ','

# reading user's config file
for line in config_file:
    if line.startswith(conf_key_split1):
        line = line.rstrip().split(conf_key_split1)
        line = line[1]

        line = line.rstrip().split(conf_key_split2)
        config_param_user.append(line[0])
        config_value_user.append(line[1])

# reading global config file
for line in config_file_global:
    if line.startswith(conf_key_split1):
        line = line.rstrip().split(conf_key_split1)
        line = line[1]

        line = line.rstrip().split(conf_key_split2)
        config_param_global.append(line[0])
        config_value_global.append(line[1])

And here is the class itself:

# class for reading config from user's and global config file the list of params names list and the list of values
class configFromFile():
    def config_from_file_userfile(self, param):
        index = config_param_user.index(param)
        if config_value_user[index]:
            config_value = config_value_user[index]
        else:
            print('The value of the parameter "', param, '" was not found in', cmd_parameter)
            exit(-1)

        return config_value

    def config_from_file_global(self, param):
        index = config_param_global.index(param)
        if config_value_global[index]:
            config_value = config_value_global[index]
        else:
            print('The value of the parameter "', param, '" was not found in', cmd_parameter_global)
            exit(-1)

        return config_value

    def main(self, param):
        if param in config_param_global:
            config = self.config_from_file_global(param)
        elif param in config_param_user:
            config = self.config_from_file_userfile(param)
        else:
            print('The parameter "', param, '" was not found in', cmd_parameter, 'and in', cmd_parameter_global)
            exit(-1)

        return config

Usage:

names = configFromFile().main('names')


Update: thanks to the comments I changed the code the following way (it's not finished yet).

cmd_parameter_user = "config1.cfg"
cmd_parameter_global = "global.cfg"

config_file_user = []
config_file_global = []

conf_key_split1 = '.'
conf_key_split2 = '='
conf_key_split3 = ','

dict_config_user = {}
dict_config_global = {}
dict_config = {}

if len(sys.argv) == 2:
    cmd_parameter_user = sys.argv[1]
else:
    print("Error: there should be only one argument after program name - config file name")
    exit(-1)

def read_file(filename, message):
# function for reading from file to list of lines
    try:
        with open(filename) as file_:
            return file_.readlines()
    except FileNotFoundError:
        print(message.format(filename))
        exit(-1)

# reading user's and global config files
config_file_user = read_file(cmd_parameter_user, "File '{}' not exists or not available")
config_file_global = read_file(cmd_parameter_global, "File '{}' not exists or not available")


def parse_list(filename, dictname):
# function for parsing list of lines into a dict
    for line in filename:
        if line.startswith(conf_key_split1):
            line = line.rstrip().split(conf_key_split1)
            line = line[1]

            (key, val) = line.split(conf_key_split2)
            dictname.update({key: val})

# parsing user's and global config files
parse_list(config_file_user, dict_config_user)
parse_list(config_file_global, dict_config_global)


def update_dicts(dictname1, dictname2):
# function for updating (merging) dicts
    dictname1.update(dictname2)
    return dictname1


def value_from_dict(param):
# function for searching the value of param in dict
    if param in dict_config:
        return dict_config.get(param)
    else:
        print('The value of the parameter "', param, '" was not found in either', cmd_parameter_global, 'or', cmd_parameter_user)
        exit(-1)

dict_config = update_dicts(dict_config_global, dict_config_user)

Usage:

names = int(value_from_dict('names'))
nrp
  • 133
  • 1
  • 5