2010-07-10 5 views
17

Normalerweise I-Code wie folgt in einer Variablen ein bestimmtes Element für immer alsLesen Sie alle Inhalte in ini-Datei in Wörterbuch mit Python

try: 
    config = ConfigParser.ConfigParser() 
    config.read(self.iniPathName) 
except ConfigParser.MissingSectionHeaderError, e: 
    raise WrongIniFormatError(`e`) 

try: 
    self.makeDB = config.get("DB","makeDB") 
except ConfigParser.NoOptionError: 
    self.makeDB = 0 

folgt Gibt es eine Möglichkeit, alle Inhalte in einem Python-Wörterbuch zu lesen ?

Zum Beispiel

 
[A] 
x=1 
y=2 
z=3 
[B] 
x=1 
y=2 
z=3 

in geschrieben

 
val["A"]["x"] = 1 
... 
val["B"]["z"] = 3 

Antwort

26

Ich schlage vor, Subklassifizieren ConfigParser.ConfigParser (oder SafeConfigParser, & c) schreibt den „geschützten“ sicher zuzugreifen (Namen mit Unterstrich beginnen - „privaten“ wären Namen mit zwei Unterstrichen beginnen, zugegriffen wird nicht einmal in Unterklassen ...):

import ConfigParser 

class MyParser(ConfigParser.ConfigParser): 

    def as_dict(self): 
     d = dict(self._sections) 
     for k in d: 
      d[k] = dict(self._defaults, **d[k]) 
      d[k].pop('__name__', None) 
     return d 

Dies die übliche Logik des Config-Parsers emuliert, und garantiert in allen Versionen von Python zu arbeiten, wo ein es ConfigParser.py Modul (bis zu 2,7, die die letzten der 2.* Serie ist - zu wissen, dass es keine zukünftigen Python 2.any Versionen geben wird, ist wie kompatibel Fähigkeit kann sein garantiert ;-).

Wenn Sie zukünftig Python 3.* Versionen unterstützen müssen (bis zu 3.1 und wahrscheinlich die bald bevorstehenden 3.2 es sollte in Ordnung sein, nur um das Modul zu allen-Klein configparser statt natürlich Umbenennung) es einige Aufmerksamkeit benötigen/zwickt ein paar Jahre später, aber ich würde nichts Größeres erwarten.

23

ich es geschafft, eine Antwort zu bekommen, aber ich erwarte, dass es sollte man besser sein.

dictionary = {} 
for section in config.sections(): 
    dictionary[section] = {} 
    for option in config.options(section): 
     dictionary[section][option] = config.get(section, option) 
+2

Ich denke, das eine sehr gute Lösung ist, warum bist du nicht glücklich mit ihm? –

+2

Dies sollte die Antwort sein, da es das Problem löst, ohne das Attribut "_sections" "private" verwenden zu müssen. Und natürlich, wenn Sie ein OrderedDict verwenden müssen, verwenden Sie das anstelle des regulären Diktats. – SizzlingVortex

+1

Das Ersetzen von 'dictionary' durch ein' defaultdict (dict) 'würde die Erstellung von Zwischendiktaten entfernen. – noxdafox

10

Die Instanzdaten für ConfigParser werden intern als verschachteltes Dict gespeichert. Anstatt es neu zu erstellen, könnten Sie es einfach kopieren.

>>> import ConfigParser 
>>> p = ConfigParser.ConfigParser() 
>>> p.read("sample_config.ini") 
['sample_config.ini'] 
>>> p.__dict__ 
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B':   {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>} 
>>> d = p.__dict__['_sections'].copy() 
>>> d 
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}} 

Edit:

Alex Martelli solution ist sauberer, robuster und schöner. Während dies die akzeptierte Antwort war, würde ich vorschlagen, stattdessen seinen Ansatz zu verwenden. Lesen Sie seinen Kommentar zu dieser Lösung für weitere Informationen.

+4

Ich habe immer keinen Zugang zu geschützten ("start-with-underscore") Namen von Attributen (und die absurde Komplikation, "__dict__" zu durchlaufen, hilft überhaupt nicht - 'd = p._sections.copy() 'ist genau gleich, einfacher und direkter). Deshalb schlug ich in meiner Antwort die Alternative vor, stattdessen eine Unterklasse zu verwenden - Unterklassen sind _expected_, um auf geschützte Attribute der Basisklasse zuzugreifen. In C++ wird dies erzwungen; in Python ist es nicht, aber das liegt daran, dass die Benutzer diszipliniert genug sein sollten, um die Durchsetzung nicht zu erzwingen ;-). –

1

Wie ini-Datei in Py analysieren?

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read('/var/tmp/test.ini') 
print config.get('DEFAULT', 'network') 

Wo test.ini Datei enthalten:

[DEFAULT] 
network=shutup 
others=talk 
6

Ich weiß, dass diese Frage vor 5 Jahren gefragt wurde, aber heute hat ich dieses dict Verständnis Dingen gemacht:

parser = ConfigParser() 
parser.read(filename) 
confdict = {section: dict(parser.items(section)) for section in parser.sections()} 
0

Eine weitere Sache, auf die Sie achten sollten, ist ConfigParser wandelt die Schlüsselwerte in Kleinbuchstaben um. Wenn Sie also die Konfigurationseinträge in ein Wörterbuch konvertieren, überprüfen Sie Ihre Anforderungen. Ich hatte deswegen ein Problem. Für mich hatte ich Kamelschlüssel, daher musste ich eine Menge Code ändern, als ich begann, das Wörterbuch anstelle von Dateien zu verwenden.ConfigParser.get() Methode intern konvertiert den Schlüssel in Kleinbuchstaben.

-1

von https://wiki.python.org/moin/ConfigParserExamples

def ConfigSectionMap(section): 
dict1 = {} 
options = Config.options(section) 
for option in options: 
    try: 
     dict1[option] = Config.get(section, option) 
     if dict1[option] == -1: 
      DebugPrint("skip: %s" % option) 
    except: 
     print("exception on %s!" % option) 
     dict1[option] = None 
return dict1