Arraywerte aus einer externen Datei laden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
hosch
User
Beiträge: 3
Registriert: Dienstag 19. Januar 2010, 19:38

Dienstag 19. Januar 2010, 19:48

Hallo,

ich möchte mit einem Script die Konfigurationswerte einer Xen-Installation auslesen.

Die Konfig schaut folgendermaßen aus:
kernel = '/boot/vmlinuz-2.6.26-2-xen-amd64'
#kommentar
ramdisk = '/boot/initrd.img-2.6.26-2-xen-amd64'
memory = '1024'
vcpus='8'
root = '/dev/sda1 ro'
disk = [
'file:/var/disk.img,sda1,w',
]
name = 'node123'
dhcp = 'dhcp'
vif = [ 'mac=00:16:3E:43:DF:D8' ]
Gibt es eine Möglichkeit, die Datei direkt in eine Konfig-Variable zu laden? Ich habe bisher nur Config-Module für csv, xml, usw. gefunden, nichts jedoch, dass das oben gezeigte Format lädt.
IoI
User
Beiträge: 68
Registriert: Dienstag 1. Dezember 2009, 11:39

Dienstag 19. Januar 2010, 19:52

Versuchs mal mit ConfigParser
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Dienstag 19. Januar 2010, 19:53

Schau dir mal das Modul ConfigParser an. Und das Tutorial ;) Das was du als Array bezeichnest, ist nämlich mit ziemlicher Sicherheit ein Dictionary oder eine Liste.
hosch
User
Beiträge: 3
Registriert: Dienstag 19. Januar 2010, 19:38

Mittwoch 20. Januar 2010, 00:57

Pekh hat geschrieben:Schau dir mal das Modul ConfigParser an. Und das Tutorial ;) Das was du als Array bezeichnest, ist nämlich mit ziemlicher Sicherheit ein Dictionary oder eine Liste.
Das Modul hab ich mir schon angesehen. ConfigParser verwendet jedoch eine leicht andere Struktur (es gibt bei der xen-config z.b. keine section). Außerdem werden die Variablen nicht korrekt geladen [wenn ich die section händisch einfüge] z.b werden Substrukturen nicht geparst außerdem wird bei Wertzuweisungen ala
key='asdf'
das Hochkomma nicht entfernt.
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Mittwoch 20. Januar 2010, 01:30

Wenn das denn - wie es aussieht - gueltige Python-Syntax ist, kannst du es auch als Modul laden, eventuell auch AST aber das waeren Kanonen.
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Mittwoch 20. Januar 2010, 07:47

Moin,

entschuldigt, wenn ich mich wieder als Ahnungsloser in Config-Objekten zu Wort melde. Aber wenn es gültige Python Syntax ist, kann man sie auch mit exec in einem leeren Dictionary als Namensraum ausführen:

Code: Alles auswählen

s = """kernel = '/boot/vmlinuz-2.6.26-2-xen-amd64'
#kommentar
ramdisk = '/boot/initrd.img-2.6.26-2-xen-amd64'
memory = '1024'
vcpus='8'
root = '/dev/sda1 ro'
disk = [
'file:/var/disk.img,sda1,w',
]
name = 'node123'
dhcp = 'dhcp'
vif = [ 'mac=00:16:3E:43:DF:D8' ]"""

dummy, result = {}, {}
exec s in dummy, result
print result
{'ramdisk': '/boot/initrd.img-2.6.26-2-xen-amd64', 'kernel': '/boot/vmlinuz-2.6.26-2-xen-amd64', 'vif': ['mac=00:16:3E:4
3:DF:D8'], 'name': 'node123', 'vcpus': '8', 'memory': '1024', 'dhcp': 'dhcp', 'disk': ['file:/var/disk.img,sda1,w'], 'ro
ot': '/dev/sda1 ro'}
dummy habe ich verwendet, da im ersten Dict (zumindest meist) ein __builtins__ angelegt wird. Statt des Dummys hätte man auch nachträglich prüfen können, ob __builtins__ im Dict ist und es gegebenermaßen entfernt. Dies war die kurze Variante, aber speicheraufwendiger.

Grüße,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Mittwoch 20. Januar 2010, 09:27

Michael Schneider hat geschrieben: dummy, result = {}, {}
exec s in dummy, result
print result[/code]
Sehr chick, kannte ich auch nocht nicht (Tagwerk vollbracht, wieder was gelernt).

a) Kann mir jemand noch mal genauer erklären was in dem ersten dict landet? Sind das die buildin objekte die er global ablegt? (hab in der API was von global und local variablen gelesen

b) der optionale Parameter "in" ist mir in diesem Fall nicht ganz klar geworden, er definiert den Scope in dem das ganze ausgeführt werden soll. Was er in diesem Fall macht sieht man ja, aber gibt es da noch andere Anwedungsszenarien für den Parameter, ausser dict's aus Strings zu parsen?

Danke schon mal für eine mögliche Erklärung :)

Grüße
D
hosch
User
Beiträge: 3
Registriert: Dienstag 19. Januar 2010, 19:38

Mittwoch 20. Januar 2010, 16:07

Michael Schneider hat geschrieben: dummy, result = {}, {}
exec s in dummy, result
Danke!
Diese 2 Zeilen sind genau das, was ich gesucht habe :)
Hab ich mir doch gedacht, dass ich keinen eigenen Parser dafür schreiben muss.
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Donnerstag 21. Januar 2010, 00:34

Hallo D!
da.dom hat geschrieben:a) Kann mir jemand noch mal genauer erklären was in dem ersten dict landet? Sind das die buildin objekte die er global ablegt? (hab in der API was von global und local variablen gelesen
Ja, Python unterscheidet zwischen zwei Namensräumen, dem Globalen und dem Lokalen. Um diese zu simulieren, werden bis zu zwei Dictionaries benötigt. Wenn exec beispielsweise eine Funktion ausführt, in der bestimmte globale Namen definiert werden, dann werden Änderungen daran im globalen Dict durchgeführt, sonst im lokalen.

Wie das __builtins__ nun ausgerechnet in das anfangs leere, globale Dict kommt, kann ich nicht genau sagen. Es wird aber damit zusammenhängen, dass diese Variablen immer global definiert sind, um auf die Grundfunktionen überhaupt zugreifen zu können.
da.dom hat geschrieben:b) der optionale Parameter "in" ist mir in diesem Fall nicht ganz klar geworden, er definiert den Scope in dem das ganze ausgeführt werden soll. Was er in diesem Fall macht sieht man ja, aber gibt es da noch andere Anwedungsszenarien für den Parameter, ausser dict's aus Strings zu parsen?
Nicht das 'in', sondern das 'exec' führt den String so aus, als ob es Quelltext in einer Python-Quellcodedatei ist. Eine Angabe von dictionaries ist nicht notwendig und wenn weggelassen wird der Code in den aktuellen Namensräumen ausgeführt. Das ist die wahrscheinlich mächtigste Funktion, da sie sich selbst generierenden Code dynamisch ausführen und so zu teuflischen Ergebnissen führen kann, gelinde gesagt. Deshalb sollte man eine Ausführung im aktuellen Namensraum tunlichst vermeiden und außerdem brauchst Du die eingelesenen Variablen ja sowieso in einem Dict.

'in' dient in diesem Fall, ebenso wie in 'enthält'-Prüfungen a la

Code: Alles auswählen

key in dict
, als Schlüsselwort in einem fest definierten Konstrukt. In letzterem Fall bewirkt es einen Aufruf der dict-Methode __contains__ mit key als Argument. Allein kann es aber niemals eine Funktion ausführen.

Ich hoffe, das beantwortet das eine oder andere.

LG,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Freitag 22. Januar 2010, 13:42

HuHu..

danke erst mal für deine ausfürliche Antwort. Das mit dem exec war mir schon mal klar, aber nur damit ich das richtig verstehe wiederhole ich mal (mit der Bitte auf Korrektur, falls was falsch ist):

Alles Variablen, Objekte und Methoden werden im Hintergrund in dictionaries abgelgt: locals() und globals() sind das? Wenn ich also eine in meinem Programm definiere, fügt er diese dem locals-dictionary einen Eintrag hinzu.. (variable='test' entspricht demnach so was wie: locals()['variable']='test'?!)

Sprich wenn ich die Datei ohne "Scope" angabe ausführe:

Code: Alles auswählen

...
exec s
print memory
...
Nutz er als "Standard" (?) Scope für Programme das locale dict und ich kann auf die Variablen direkt zugreifen. Mit der zusätzlichen Anweisung "in" gebe ich ihm aber einen expliziten Scope mit (laut API)...ok...in diesem Fall verstehe ich was er dann tut, wobei ich eher so was erwartet hätte:

Code: Alles auswählen

exec s in myDict
Viele Grüße
Dom
Antworten