我试图在python中编写一个简单的对象,它将使用ConfigParser
加载设置,将所有项目作为字典,然后将它们设置为对象的属性。
如果我不包含__setattr__
方法,这似乎有效。我可以调用“settings.top_travel”并获得答案。但是,一旦我尝试放置__setattr__
,我似乎就会收到错误。
它看起来相当递归,所以我假设Get
正在调用Set
等。在set属性部分中,我希望将其写回配置文件。因此,只要其中一个设置属性发生更改,它就会存储回文件来源。
您将在下面找到代码和错误。
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
错误:
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
答案 0 :(得分:5)
问题是设置self.configuration会调用self.__setattr__
您可以通过将分配更改为对超类__setattr__
的调用来规避这一点:
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")))
答案 1 :(得分:5)
使__setattr__
对不以'_'
开头的属性独占,并将配置存储在self._configuration中,然后添加一个要求,即配置文件不接受名称以下划线开头的选项。< / p>
def __setattr__(self, attribute, value):
if attribute.startswith('_'):
super(settingsFile, self).__setattr__(attribute, value)
return
# Clever stuff happens here
答案 2 :(得分:-2)
无论你使用ConfigParser做什么聪明的东西,都会无限递归。我无法确定,因为我没有看到代码,但如果您正在使用递归,请确保涵盖所有基本情况。