I'm using the RawConfigParser
to read and update an ini style configuration file. This works all without problems in the standard configuration.
My problem is that I'm reading different config files in the same script. Without going too much into detail, when I read the second config file its values are merged with the first ini file.
Original contents of both ini files
infile_1.ini
[section]
option = Original value
extraoption = not in ini file 2
inifile_2.ini
[section]
option = Original value
This is the code I use to alter the contents of the ini file. It's a short piece of code to reproduce the problem
import ConfigParser
class status_file:
myConfig = ConfigParser.RawConfigParser()
myConfig.optionxform = str
def __init__(self, str_statusfile):
self.myConfig.read( str_statusfile)
self.statusfile = str_statusfile
def option(self, new_value):
self.myConfig.set("section","option",new_value)
with open( self.statusfile, "w") as ini_out:
self.myConfig.write( ini_out )
statusfiles = ['inifile_1.ini', 'inifile_2.ini']
for myStatus in statusfiles:
myConfig = status_file(myStatus)
myConfig.option("Something new")
After this code is executed the content of the ini files has changed as wished. But in the second ini file, options from the first ini file are merged.
infile_1.ini
[section]
option = Something New
extraoption = not in ini file 2
inifile_2.ini
[section]
option = Something New
extraoption = not in ini file 2
Is there some way I can reset the ConfigParser
content or some other solution?
I guess it's related to construction and deconstruction of the ConfigParser
object?
I tried it without the class and then there is no problem.
I'm a beginner in Python so this may not be the best way of handling this.
The real application is dynamic in the sense that the number of ini files and the location change during use of the application. The list of ini files is built with os.listdir(folder)
The confusion you are making is that defining the ConfigParser like this:
class status_file:
myConfig = ConfigParser.RawConfigParser()
myConfig.optionxform = str
def __init__(self, str_statusfile):
...
makes the myConfig
attribute a class attribute for status_file
, unlike, say, Java.
Thus, when you parse the second file, the same config will parse it, and merge its options with he first file it parsed.
To avoid your problem, just create the parser as an instance attribute, inside the __init__
method:
class status_file(object):
def __init__(self, str_statusfile):
self.myConfig = ConfigParser.RawConfigParser()
self.myConfig.optionxform = str
...
As a side note, if you are using Python version 2.x, your class should inherit from object
. Otherwise you will have old-style (pre-python2.2) classes that might surprise you with lots of subtle problems.
This is common python mistake for beginners. I assume you know language like Java or C++, don't you?
In your class myConfig
is attribute of the class, not it's instances. Default Python behaviour is to look first in instance attributes, then in class attributes, so self.myConfig
is exactly the same parser in both instances. See this for extended details.
Solution for you is to create and configure parser in constructor (__init__
), instead of class declaration.
This may help you understand why myConfig is class attribute, not instance attribute: When you write something like this:
class A(B, C):
def foo(x):
return 2*x
it is just syntax sugar for:
def foo(x):
return 2*x
A = type("A", (B, C), {"foo": foo})
del foo
This may come in handy if you ever need to create new class dynamically.
As A
is class, it's __call__
method finally leads to calling it's __new__
and __init__
methods, which will cause creation of new instance, which will share the same object A
as it's __class__
attribute (this is simplification, it's not all that happens inside, but for general Pythoning it's enough ;) ).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With