By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,100 Members | 2,495 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,100 IT Pros & Developers. It's quick & easy.

Creating "Clean" INI files

P: 56
Hello.

I've been using the ConfigParser module, which is a great module, gets the job done, but when it creates INI files its hard to read them. Heres what I mean, currently, when written to, the INI files look something like this:

Expand|Select|Wrap|Line Numbers
  1. [a]
  2. something = somethingelse
  3. [c]
  4. 5 = True
  5. 1 = false
  6. 3 = False
  7. 2 = True
  8. 4 = True
  9. [b]
  10. d = 1
  11. a = 3
  12. c = 6
  13. b = 2
I'd like to modify the module to make them look like this:

Expand|Select|Wrap|Line Numbers
  1. [a]
  2. something = somethingelse
  3. [b]
  4. a = 3
  5. b = 2
  6. c = 6
  7. d = 1
  8. [c]
  9. 1 = false
  10. 2 = True
  11. 3 = False
  12. 4 = True
  13. 5 = True
  14.  
See what I mean? Anyone have any ideas on how I can accomplish this? thanks.
May 21 '07 #1
Share this Question
Share on Google+
9 Replies


bartonc
Expert 5K+
P: 6,596
Hello.

I've been using the ConfigParser module, which is a great module, gets the job done, but when it creates INI files its hard to read them. Heres what I mean, currently, when written to, the INI files look something like this:

Expand|Select|Wrap|Line Numbers
  1. [a]
  2. something = somethingelse
  3. [c]
  4. 5 = True
  5. 1 = false
  6. 3 = False
  7. 2 = True
  8. 4 = True
  9. [b]
  10. d = 1
  11. a = 3
  12. c = 6
  13. b = 2
I'd like to modify the module to make them look like this:

Expand|Select|Wrap|Line Numbers
  1. [a]
  2. something = somethingelse
  3. [b]
  4. a = 3
  5. b = 2
  6. c = 6
  7. d = 1
  8. [c]
  9. 1 = false
  10. 2 = True
  11. 3 = False
  12. 4 = True
  13. 5 = True
  14.  
See what I mean? Anyone have any ideas on how I can accomplish this? thanks.
Cool... Makes me wish I was using CP. Here's the idea:
Derive from CP:
Expand|Select|Wrap|Line Numbers
  1. class MyConfigParser(ConfigParser):
  2.     # and override the write method
  3.     def write(self, fp):
  4.         # and sort the dictionary keys before calling fp.write()
.
Sounds like fun. If you need help, we're here.
May 21 '07 #2

P: 56
okay, sorting the sections is easy, thats just a list. but i've never sorted a dictionary before. how would i sort the keys?

Expand|Select|Wrap|Line Numbers
  1. for (key, value) in self._sections[section].items():
May 21 '07 #3

bartonc
Expert 5K+
P: 6,596
okay, sorting the sections is easy, thats just a list. but i've never sorted a dictionary before. how would i sort the keys?

Expand|Select|Wrap|Line Numbers
  1. for (key, value) in self._sections[section].items():
I know that there is a better way, but at the moment this works:
Make a list from the dict.keys(), sort it, iterate over it:

>>> d = dict(a=1,b=2,c=3)
>>> d
{'a': 1, 'c': 3, 'b': 2}

>>> l = d.keys()
>>> l
['a', 'c', 'b']

>>> l.sort()
>>> l
['a', 'b', 'c']

>>> for key in l:
... print d[key]
...
1
2
3
>>>
May 21 '07 #4

bartonc
Expert 5K+
P: 6,596
I know that there is a better way, but at the moment this works:
Make a list from the dict.keys(), sort it, iterate over it:

>>> d = dict(a=1,b=2,c=3)
>>> d
{'a': 1, 'c': 3, 'b': 2}

>>> l = d.keys()
>>> l
['a', 'c', 'b']

>>> l.sort()
>>> l
['a', 'b', 'c']

>>> for key in l:
... print d[key]
...
1
2
3
>>>
Expand|Select|Wrap|Line Numbers
  1. for key in l:
  2.     value = self._sections[section][key]
  3.     # ...
May 21 '07 #5

P: 56
Okay, this is what I came up with.

Expand|Select|Wrap|Line Numbers
  1.     def write(self, fp):
  2.         """Write an .ini-format representation of the configuration state."""
  3.         if self._defaults:
  4.             fp.write("[%s]\n" % DEFAULTSECT)
  5.             for (key, value) in self._defaults.items():
  6.                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
  7.             fp.write("\n")
  8.         sections = sorted(self._sections)
  9.         for section in sections:
  10.             fp.write("[%s]\n" % section)
  11.             d = self._sections[section].items()
  12.             l = sorted(d.keys())
  13.             for key in l:
  14.                 value = self._sections[section][key]
  15.                 if key != "__name__":
  16.                     fp.write("%s = %s\n" %
  17.                              (key, str(value).replace('\n', '\n\t')))
  18.             fp.write("\n")
But it generates this error:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python25\lib\ConfigParser2.py", line 372, in write
l = sorted(d.keys())
AttributeError: 'list' object has no attribute 'keys'
May 23 '07 #6

bartonc
Expert 5K+
P: 6,596
Okay, this is what I came up with.

Expand|Select|Wrap|Line Numbers
  1.     def write(self, fp):
  2.         """Write an .ini-format representation of the configuration state."""
  3.         if self._defaults:
  4.             fp.write("[%s]\n" % DEFAULTSECT)
  5.             for (key, value) in self._defaults.items():
  6.                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
  7.             fp.write("\n")
  8.         sections = sorted(self._sections)
  9.         for section in sections:
  10.             fp.write("[%s]\n" % section)
  11.             d = self._sections[section].items()
  12.             l = sorted(d.keys())
  13.             for key in l:
  14.                 value = self._sections[section][key]
  15.                 if key != "__name__":
  16.                     fp.write("%s = %s\n" %
  17.                              (key, str(value).replace('\n', '\n\t')))
  18.             fp.write("\n")
But it generates this error:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python25\lib\ConfigParser2.py", line 372, in write
l = sorted(d.keys())
AttributeError: 'list' object has no attribute 'keys'
I'll just do a little mark up, so you'll understand what you've written:
Expand|Select|Wrap|Line Numbers
  1.     def write(self, fp):
  2.         """Write an .ini-format representation of the configuration state."""
  3.         if self._defaults:
  4.             fp.write("[%s]\n" % DEFAULTSECT)
  5.             for (key, value) in self._defaults.items():
  6.                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
  7.             fp.write("\n")
  8.         sections = sorted(self._sections)
  9.         for section in sections:
  10.             fp.write("[%s]\n" % section)
  11.             # dict.items returns a list of (key, value) tuples
  12.             ### d = self._sections[section].items()
  13.             # if you want you can copy the section
  14.             d = self._sections[section]
  15.             # instead of items(), we're using keys() and d[key] for the pair
  16.             l = sorted(d.keys())
  17.             for key in l:
  18.                 # then use the copy here too
  19.                 value = d[key]
  20.                 #### value = self._sections[section][key]
  21.                 if key != "__name__":
  22.                     fp.write("%s = %s\n" %
  23.                              (key, str(value).replace('\n', '\n\t')))
  24.             fp.write("\n")
Looks great otherwise.
May 23 '07 #7

bartonc
Expert 5K+
P: 6,596
I'll just do a little mark up, so you'll understand what you've written:
Expand|Select|Wrap|Line Numbers
  1.     def write(self, fp):
  2.         """Write an .ini-format representation of the configuration state."""
  3.         if self._defaults:
  4.             fp.write("[%s]\n" % DEFAULTSECT)
  5.             for (key, value) in self._defaults.items():
  6.                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
  7.             fp.write("\n")
  8.         sections = sorted(self._sections)
  9.         for section in sections:
  10.             fp.write("[%s]\n" % section)
  11.             # dict.items returns a list of (key, value) tuples
  12.             ### d = self._sections[section].items()
  13.             # if you want you can copy the section
  14.             d = self._sections[section]
  15.             # instead of items(), we're using keys() and d[key] for the pair
  16.             l = sorted(d.keys())
  17.             for key in l:
  18.                 # then use the copy here too
  19.                 value = d[key]
  20.                 #### value = self._sections[section][key]
  21.                 if key != "__name__":
  22.                     fp.write("%s = %s\n" %
  23.                              (key, str(value).replace('\n', '\n\t')))
  24.             fp.write("\n")
Looks great otherwise.
Looking at it, the list returned by items() may actually be sortable: you could try
Expand|Select|Wrap|Line Numbers
  1.     def write(self, fp):
  2.         """Write an .ini-format representation of the configuration state."""
  3.         if self._defaults:
  4.             fp.write("[%s]\n" % DEFAULTSECT)
  5.             for (key, value) in self._defaults.items():
  6.                 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
  7.             fp.write("\n")
  8.         sections = sorted(self._sections)
  9.         for section in sections:
  10.             fp.write("[%s]\n" % section)
  11.             # dict.items returns a list of (key, value) tuples
  12.             sectList = self._sections[section].items()
  13.             sectList.sort()
  14.             # or your sorted() trick (which is what I was trying to think of earlier)
  15.             for key, value in sectList:
  16.                 if key != "__name__":
  17.                     fp.write("%s = %s\n" %
  18.                              (key, str(value).replace('\n', '\n\t')))
  19.             fp.write("\n")
May 23 '07 #8

P: 56
Thanks for that, Works great.
May 24 '07 #9

bartonc
Expert 5K+
P: 6,596
Thanks for that, Works great.
You are quite welcome. Any time, really.
May 24 '07 #10

Post your reply

Sign in to post your reply or Sign up for a free account.