views:

37

answers:

2

I have a configuration file (feedbar.cfg), having the following content:

[last_session]
last_position_x=10
last_position_y=10

After I run the following python script:

#!/usr/bin/env python

import pygtk
import gtk
import ConfigParser
import os
pygtk.require('2.0')

class FeedbarConfig():
 """ Configuration class for Feedbar.
 Used to persist / read data from feedbar's cfg file """
 def __init__(self, cfg_file_name="feedbar.cfg"):
  self.cfg_file_name = cfg_file_name
  self.cfg_parser = ConfigParser.ConfigParser()
  self.cfg_parser.readfp(open(cfg_file_name))

 def update_file(self):
  with open(cfg_file_name,"wb") as cfg_file:
   self.cfg_parser.write(cfg_file)

 #PROPERTIES 
 def get_last_position_x(self):
  return self.cfg_parser.getint("last_session", "last_position_x")
 def set_last_position_x(self, new_x):
  self.cfg_parser.set("last_session", "last_position_x", new_x)
  self.update_file()

 last_position_x = property(get_last_position_x, set_last_position_x)

if __name__ == "__main__":
 #feedbar = FeedbarWindow()
 #feedbar.main()
 config = FeedbarConfig()
 print config.last_position_x
 config.last_position_x = 5
 print config.last_position_x

The output is:

10
5

But the file is not updated. The cfg file contents remain the same.

Any suggestions ?

Is there another way to bind config information from a file into a python class ? Something like JAXB in Java (but not for XML, just .ini files).

Thanks!

+3  A: 

Edit2: The reason why your code is not working is because FeedbarConfig must inherit from object to be a new-style class. Properties do not work with classic classes.:

So the solution is to use

class FeedbarConfig(object)

Edit: Does JAXB read XML files and convert them to objects? If so, you may want to look at lxml.objectify. This would give you an easy way to read and save your configuration as XML.


Is there another way to bind config information from a file into a python class ?

Yes. You could use shelve, marshal, or pickle to save Python objects (e.g. a list, or dict).

Last time I tried to use ConfigParser, I ran into some problems:

  1. ConfigParser does not handle multi-line values well. You have to put whitespace on subsequent lines, and once parsed, the whitespace is removed. So all your multi-line strings get converted into one long string anyway.
  2. ConfigParser downcases all option names.
  3. There is no way to guarantee the order in which the options are written to file.

Although, these are not the issue that you currently face, and although saving the file may be easy to fix, you may want to consider using one of the other modules to avoid future problems.

unutbu
Yes that was the problem.Thank you!
Andrei Ciobanu
+2  A: 

[I would put this in a comment, but I'm not permitted to comment at this time]

As an aside, you may want to use decorator-style properties, they make things look better, at least in my opinion:

 #PROPERTIES

 @property 
 def position_x(self):
  return self.cfg_parser.getint("last_session", "last_position_x")

 @position_x.setter
 def position_x(self, new_x):
  self.cfg_parser.set("last_session", "last_position_x", new_x)
  self.update_file()

Also, according to python docs, SafeConfigParser is the way to go for new applications:

"New applications should prefer this version if they don’t need to be compatible with older versions of Python." -- http://docs.python.org/library/configparser.html

babbitt