2009-05-13 19 views
4

私は、INIファイルをPythonオブジェクトとしてマップしたいと思います。だから、ファイルが持っている場合:マップINI値に__setattr__&__getattr__を使用する方法は?

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

それから私がしたい:

c = Configuration('sample.ini') 

c.UserOptions.SamplePort = 90 

私は SETATTR を探していますが、私は再帰エラーが発生します。

これは私が持っているものです。self.__parser.set('UserOptions',item, value)に私はエラーを取得する理由

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) 

は今、私は疑問に思います。私は秘書の文書を読み、私は何をすべきか分からない。私は、フィールド名と最初の外観を持つ辞書を格納する必要があると思うが、どのように?

+1

組み込みの設定パーサーを使用していないのはなぜですか? http://docs.python.org/library/configparser.html –

+0

私は使用していますが、インポート行を挿入するのを忘れています... – mamcx

答えて

4

リクエストに応じてセクションを取得しようとしています。しかし、セクションやオプションを繰り返し処理し、__init__の属性として追加するほうがはるかに簡単です。私は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

Really Quite Nice。 –

+0

OPはConfigParserも使用していました(インポートを含めるのを忘れただけです)。 –

4

あなたの問題はSection.__init__である使用する必要がありながら、あなたは__setattr__で属性を割り当てるhere説明されています。あなたはそれがあなたの__setattr__メソッドを呼び出すself.__name = name設定すると、__dict__にキーを見つけることができませんので、だから今、それはself.__parserを必要と

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

に行きます。

まだ設定されていません。だからそれは__getattr__を使って取得しようとします。それはself.__parserを探して送信します。まだ設定されていないだからそれは__getattr__を使って取得しようとします。だから... ...あなたはポイントを得るこれを回避する:-)

一つの方法は、__name__parserは、初期化時に適切に設定されていることを確認します。この

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

ようSection.__setattr__に条件を追加することです。

+0

Auch! 入力いただきありがとうございます。 – mamcx

関連する問題