2009-05-13 4 views
4

Я хочу отобразить INI-файл как объект python. Так что, если файл есть:Как использовать __setattr__ & __getattr__ для значений карты INI?

[UserOptions] 
SampleFile = sample.txt 
SamplePort = 80 
SampleInt = 1 
Sample = Aja 
SampleDate = 10/02/2008 

Тогда я хочу:

c = Configuration('sample.ini') 

c.UserOptions.SamplePort = 90 

Я ищу SetAttr, но я получаю ошибку рекурсии.

Это то, что у меня есть:

class Configuration: 
    def __init__ (self, fileName): 
     cp = SafeConfigParser() 
     cp.read(fileName) 
     self.__parser = cp 
     self.fileName = fileName 

    def __getattr__ (self, name): 
     if name in self.__parser.sections(): 
      return Section(name, self.__parser) 
     else: 
      return None 

    def __str__ (self): 
     p = self.__parser 
     result = [] 
     result.append('<Configuration from %s>' % self.fileName) 
     for s in p.sections(): 
      result.append('[%s]' % s) 
      for o in p.options(s): 
       result.append('%s=%s' % (o, p.get(s, o))) 
     return '\n'.join(result) 

class Section: 
    def __init__ (self, name, parser): 
     self.__name = name 
     self.__parser = parser 

    def __getattr__ (self, name): 
     if self.__dict__.has_key(name):  # any normal attributes are handled normally 
      return __getattr__(self, item) 
     else: 
      return self.__parser.get(self.name, name) 

    def __setattr__(self, item, value): 
     """Maps attributes to values. 
     Only if we are initialised 
     """ 
     if self.__dict__.has_key(item):  # any normal attributes are handled normally 
      dict.__setattr__(self, item, value) 
     else: 
      self.__parser.set('UserOptions',item, value) 

Теперь я удивляюсь, почему в self.__parser.set('UserOptions',item, value) я получаю ошибку. Я читал в документах pythons, и я не понимаю, что делать. Я подозреваю, что мне нужно хранить dict с именем поля и сначала посмотреть там, но как?

+1

Почему вы не используете встроенный синтаксический анализатор? http://docs.python.org/library/configparser.html –

+0

Я использую, но я забываю вставить строку импорта ... – mamcx

ответ

4

Вы пытаетесь получить разделы по запросу. Но гораздо проще перебирать разделы и опции и добавлять их как атрибут в __init__. Я также отредактировал свой пример для поддержки setattr. Вы проблема объясняется here вы назначаете атрибуты в __setattr__ в то время как вы должны использовать __dict__ вместо

from ConfigParser import SafeConfigParser 

class Section: 
    def __init__(self, name, parser): 
     self.__dict__['name'] = name 
     self.__dict__['parser'] = parser 

    def __setattr__(self, attr, value): 
     self.__dict__[attr] = str(value) 
     self.parser.set(self.name, attr, str(value)) 

class Configuration(object): 
    def __init__(self, fileName): 
     self.__parser = SafeConfigParser() 
     self.__parser.read(fileName) 
     self.fileName = fileName 
     for section in self.__parser.sections(): 
      setattr(self, section, Section(section, self.__parser)) 
      for option in self.__parser.options(section): 
       setattr(getattr(self, section), option, 
         self.__parser.get(section, option)) 

    def __getattr__(self, attr): 
     self.__parser.add_section(attr) 
     setattr(self, attr, Section(attr, self.__parser)) 
     return getattr(self, attr) 

    def save(self): 
     f = open(self.fileName, 'w') 
     self.__parser.write(f) 
     f.close() 

c = Configuration('config.ini') 

print dir(c) -> will print all sections 
print dir(c.UserOptions) -> will print all user options 
print c.UserOptions.sampledate 

c.new.value = 10 
c.save() 
+0

На самом деле ничего хорошего. –

+0

OP также использовал ConfigParser (просто забыли включить импорт). –

4

Ваша проблема заключается в Section.__init__. При установке self.__name = name он называет свой метод __setattr__, не находит ключ в __dict__ так Так что теперь нужно self.__parser он идет к

self.__parser.set('UserOptions',item, value) 

.

Которая еще не была настроена. Поэтому он пытается получить его, используя __getattr__. Который отправляет его в поисках self.__parser. Который еще не установлен. Поэтому он пытается получить его, используя __getattr__. Итак ... вы получите точку :-)

Один из способов избежать этого, добавив условие в Section.__setattr__ как этот

if item.startswith('_') or self.__dict__.has_key(item): 
    ^^^^^^^^^^^^^^^^^^^^^^^ 
    ... 

, который будет убедиться, что __name и __parser установлены правильно при инициализации.

+0

Auch! Спасибо за ввод. – mamcx

 Смежные вопросы

  • Нет связанных вопросов^_^