2010-11-26 38 views
2

Je suis en train d'écrire un simple objet en python qui charge les paramètres à l'aide ConfigParser, obtenir tous les éléments comme un dictionnaire, puis définissez les attributs comme pour l'objet.Erreur récursive lors de l'introduction setattr en python

Cela semble fonctionner si ne pas inclure une méthode __setattr__. Je peux appeler "settings.top_travel" et obtenir la réponse. Cependant, dès que j'essaie de mettre un __setattr__, il me semble qu'il y a une erreur.

Cela semble assez récursif, donc je suppose que Get appelle Set, etc. Dans la partie Attribut d'ensemble, je souhaite la réécrire dans le fichier de configuration. Ainsi, chaque fois que l'un des attributs de paramètres change, il est stocké dans le fichier d'où il provient.

Ci-dessous vous trouverez le code et l'erreur.

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 

Erreur:

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 
+1

Peut-être vous voulez juste http://www.voidspace.org.uk/python/configobj.html –

+0

Quelle est l'erreur spécifique? Par exemple. ValueError, etc. –

+0

@Rafe: J'ai mis à jour l'erreur au bas de mon message d'origine avec un message d'erreur plus complet. – Schodemeiss

Répondre

5

Le problème est que la mise en self.configuration invoque self.__setattr__

Vous pouvez contourner qu'en changeant l'affectation à un appel à __setattr__ de la super classe:

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

L'objet .__ setattr __() prend 3 paramètres. Vous avez oublié de passer le 'soi' comme le premier. – edon

+0

Fixé. Bonne prise, merci! –

-2

Quelle que soit intelligent des choses que vous faites avec ConfigParser est récursion infinie. Je ne peux pas être certain parce que je ne vois pas le code, mais si vous utilisez la récursivité, assurez-vous de couvrir tous vos cas de base.

5

Faire __setattr__ exclusive aux attributs ne démarre pas avec '_' et stockez la configuration dans self._configuration, puis ajoutez une exigence selon laquelle les fichiers de configuration n'acceptent pas les options dont le nom commence par un trait de soulignement.

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