-1

I want to read a config file and get tag value pairs in dictionary. Code need to stip whitespace, new line and only do tag value pairs as dictionary key value. Also, need to ignore comments (starting with #)

Please note I don't have much experience working with Python so happy to be pointed out best way to achieve it or improve the whole code.

File Example:
Parser.field_msgtypes.currency = GBP,EUR
Listener.mode = //blp/ref
Parser.field_mappings.ID_SEC = SECID
Engine.session.UATD.connection.transacted = 0
InternalMessage.formatType = STRB
InternalMessage.defaultVersionId = 

Here is my code:

class ConfigFileReader:
    file_prefix = 'import';
    file_suffix = 'properties';
    pfd = '/user/myusername/dev/';
    pf = '/user/myusername/';

    def setConfigFileList(self):

        genFile = [arg for arg in self.args[1:] if arg]; #ignore filename

        custom_file_middle = None;

        for arg in genFile:

            if custom_file_middle is None:
                custom_file_middle = arg;
            else:
                custom_file_middle = ".".join([custom_file_middle,arg]);

            custom_file = ".".join([self.file_prefix,custom_file_middle,self.file_suffix]);
            custom_file_path_pfd = "".join([self.pfd,custom_file]);
            custom_file_path_pf = "".join([self.pf,custom_file]);

            if os.path.exists(custom_file_path_pfd):
                print ("Loading custom file...... %s" % custom_file_path_pfd);
                self.dict_file_pfd[custom_file] = custom_file_path_pfd;
            elif os.path.exists(custom_file_path_pf):
                print ("Loading custom file...... %s" % custom_file_path_pf);
                self.dict_file_pf[custom_file] = custom_file_path_pf;
            else:
                print ("File not found......[%s] [%s]" % (custom_file,arg));

    def loadConfigFiles(self):
        self.loadConfigKeys(self.dict_file_pfd);
        self.loadConfigKeys(self.dict_file_pf);


    def loadConfigKeys(self,dict_file):

        for key in dict_file:
            file_path = dict_file[key];
            filename = key;

            list_tvp = [];
            with open(file_path,'r') as f:
                list_tvp = [line.strip() for line in f if line.strip() and not line.startswith('#')];

            self.dict_config.update(dict((each.split("=")[0].strip(),each.split("=")[1].strip()) for each in list_tvp if each.split("=")[0].strip() not in self.dict_config));

if __name__ == '__main__':
   args = sys.argv;

   config_reader = ConfigFileReader(args);
   config_reader.setConfigFileList();
   config_reader.loadConfigFiles();

   for key,value in config_reader.dict_config.items():
      print key,"=",value;

I want to change this as I feel there must be a efficient and readable version of this.

self.dict_config.update(dict((each.split("=")[0].strip(),each.split("=")[1].strip()) for each in list_tvp if each.split("=")[0].strip() not in self.dict_config));
Ajay Kumar
  • 21
  • 5
  • 1
    Did you check out this module? https://docs.python.org/3/library/configparser.html – myke Feb 05 '20 at 08:32
  • Thanks. I'll check this module. Most of existing files are simple tag value pair and doesn't follow INI file protocol. – Ajay Kumar Feb 05 '20 at 09:02
  • I get ```MissingSectionHeaderError``` as there is no header in the file. So back to normal reading and parsing – Ajay Kumar Feb 05 '20 at 09:09

2 Answers2

1

Might I suggest writing it as a normal loop:

for each in list_tvp:
   key, value = [v.strip() for v in each.split("=")]
   if key not in self.dict_config:
      self.dict_config[key] = value

I don't like the second line. And the third and fourth might be better as:

self.dict_config.setdefault(key, value)
Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • Thanks. I like simplicity of this. I did a slight change to cater for different scenarios from flie: ```key, value = [v.strip() for v in each.split("=",1)]```. This will allow blank Tags and Tags with more than one '='. – Ajay Kumar Feb 05 '20 at 09:35
  • Wish I could upvote it but not old enough on SO to do that.... – Ajay Kumar Feb 05 '20 at 09:42
0

I suggest using ConfigParser, enhancing it slightly to work without Section Headers, as explained here:

Using ConfigParser to read a file without section name

myke
  • 479
  • 3
  • 14