在python中引入setattr时出现递归错误

发布于 2024-10-05 07:57:14 字数 2206 浏览 3 评论 0原文

我正在尝试用 python 编写一个简单的对象,它将使用 ConfigParser 加载设置,将所有项目作为字典获取,然后将它们设置为对象的属性。

如果我包含 __setattr__ 方法,这似乎有效。我可以拨打“settings.top_travel”并得到答案。但是,当我尝试输入 __setattr__ 时,我似乎收到了错误。

它看起来相当递归,所以我假设 Get 正在调用 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦醒灬来后我 2024-10-12 07:57:14

问题是设置 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")))

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")))
思慕 2024-10-12 07:57:14

__setattr__ 设为不以 '_' 开头的属性独占,并将配置存储在 self._configuration 中,然后添加一个要求,即配置文件不接受名称开头的选项带下划线。

def __setattr__(self, attribute, value):
     if attribute.startswith('_'):
          super(settingsFile, self).__setattr__(attribute, value)
          return
     # Clever stuff happens here

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
鯉魚旗 2024-10-12 07:57:14

无论您使用 ConfigParser 做什么聪明的事情,都会无限递归。我不能确定,因为我没有看到代码,但如果您使用递归,请确保涵盖所有基本情况。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文