Reputation: 1174
I am trying to write a simple object in python that will load up settings using ConfigParser
, get all the items as a dictionary, then set those as attributes for the object.
This seems to work if I don't include a __setattr__
method. I can call "settings.top_travel" and get the answer back. However, as soon as I try and put a __setattr__
, I seem to get an error.
It looks fairly recursive, so I assume Get
is calling Set
, etc. In the set attribute part, I wish to make it write back to the configuration file. So, whenever one of the settings attributes changes, it gets stored back in the file where it came from.
Below you will find the code and the error.
import ConfigParser
class settingsFile(object):
def __init__(self):
"""
Reloads the configuration file and returns a dictionary with the
settings :
[config]
top_travel = 250
"""
# Create a configuration object and read in the file
configuration = ConfigParser.ConfigParser()
configuration.read('config/config.cfg')
# Return all the "config" section as a list and convert to a dictionary
self.configuration = dict(configuration.items("config"))
def refresh(self):
self.__init__()
def __getattr__(self, attr):
return self.configuration[attr]
def __setattr__(self, attr, value):
print attr, " is now ", value
# Do some clever storing with ConfigParser
if __name__ == "__main__":
settings = settingsFile()
print settings.top_travel
settings.top_travel = 600
print settings.top_travel
Error:
Traceback (most recent call last):
File "/home/stuff/Documents/Software/Python/dBControllers v2/dBControllers.py", line 52, in <module>
settings = settingsFile()
File "/home/stuff/Documents/Software/Python/dBControllers v2/dBControllers.py", line 37, in __init__
self.configuration = dict(configuration.items("config"))
File "/home/stuff/Documents/Software/Python/dBControllers v2/dBControllers.py", line 47, in __setattr__
print self.configuration[attr], " is now ", value
File "/home/stuff/Documents/Software/Python/dBControllers v2/dBControllers.py", line 44, in __getattr__
return self.configuration[attr]
File "/home/stuff/Documents/Software/Python/dBControllers v2/dBControllers.py", line 44, in __getattr__
return self.configuration[attr]
......
RuntimeError: maximum recursion depth exceeded
Upvotes: 3
Views: 2854
Reputation: 29967
The problem is that setting self.configuration invokes self.__setattr__
You can circumvent that by changing the assignment to a call to __setattr__
of the super class:
class settingsFile(object):
def __init__(self):
...
# Return all the "config" section as a list and convert to a dictionary
object.__setattr__(self, 'configuration', dict(configuration.items("config")))
Upvotes: 5
Reputation: 21055
Make __setattr__
exclusive to attributes not starting with '_'
, and store the configuration in self._configuration, then add a requirement that configuration files don't accept options whose names start with an underscore.
def __setattr__(self, attribute, value):
if attribute.startswith('_'):
super(settingsFile, self).__setattr__(attribute, value)
return
# Clever stuff happens here
Upvotes: 5
Reputation: 76955
Whatever clever stuff you're doing with ConfigParser is recursing infinitely. I can't be certain because I don't see the code, but if you're using recursion, make sure you cover all of your base cases.
Upvotes: -3