Dictionary aus anderen Datei einlesen..

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.
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Hallo, zusammen!

Eines vorweg: Ich bin ein absoluter Neuling in Pyton, möchte es aber lernen.

Ich habe derzeit ein Program, welches ich mit der Hilfe eines andern Forums (da spezielles Modul für die InSim Programmierung eines Computerspiels) auch lauffähig erstellen konnte.

Nun habe ich aber folgendes Problem:

Das Programm verbindet sich mit allen in einem Dictionary angegebenen Servern ({port: IP, port: IP.....}) und führt dann die entsprechenden Aktionen aus.

Nun möchte ich das Programm aber weitergeben und dies soll in einer EXE geschehen, damit der Endanwender kein Python installiert haben muss.

Damit das Programm aber konfigurierbar bleibt, möchte ich das Dictionary aus einer Knfigurationsdatei einlesen...

Doch da komme ich nicht weiter :( Die Methode mit file.readlines gibt mir ja nur eine Liste - und kein Dictionary... So müsste ich dann ja aus 2 Dateien einmal die Ports und dann die IPs einlesen und diese dann in ein Dictionary zusammensetzten...

Kann mir da jemad weiterhelfen, wich ich es bewerkstelligen kann, das ich eine leicht konfigurierbare txt datei habe, aus der ich dann die Daten als Dictionary auslesen kann? Die Prickel Variante (die haben ich nur in einem ganz kurzen Überbick gesehen) nutzt ja txt Dateien, die nicht so ganz einfach editierbar sind...

Vielen Dank schonmal!
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Du könntest die Daten in XML-Dateien speichern und dann mit deiunem Programm auslesen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

"Prickel" ist gut! :D

Aus deiner Ablehung von pickle schließe ich, DASS du die Dateien auch durch andere Programme oder per Hand editieren willst. Wenn nicht: Nimm doch pickle.

Ansonsten ist es eher eine Frage, wie du die Daten in der txt-Datei ablegst.
Wenn du sie zeilenweise als Zeichenkette "port:IP" abspeicherst, kannst du sie zeilenweise wieder einlesen, am ":" splitten und in ein Dictionary stecken.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Crady hat geschrieben: Damit das Programm aber konfigurierbar bleibt, möchte ich das Dictionary aus einer Knfigurationsdatei einlesen...
Wenn du ein Modul suchst, um Konfigurationsdateien zu erstellen/lesen/ändern, dann guck dir mal ConfigParser an.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Oder ConfigObj
Bastelt/liest wie ConfigParser .ini-Konfigurationsdateien.
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Hallo, zusammen!

vielen Dank erstmal für die Antworten :)

Zu Prickel: Ja, das Problem ist, dass das Konfigurationsfile händisch editiert werden soll.

Mit ConfigParser habe ich das Problem, dass ich nur einen String auslesen kann und somit keine "port:IP" Kompination in einem Dictionary bekomme, die ich dann zum verbinden mit den Servern auslesen kann.

Mit ConfigObj komme ich leider irgendwie nicht zurecht...

Also habe ich versucht, das textfile zeilenweise einzulesen, dann die "port:IP" Kombination zu teilen um sie dann ins dictionary zu schreiben.

Das funktioniert auch ganz gut... ABER: Leider habe ich hinter der IP immer noch den Zeilenschalter "/n"... Ich kann hier jetzt leider nicht testen, ob er einfach ignoriert wird und es trotzem geht... Oder kann ich den noch irgendwie weglöschen?

Hier mein Code soweit:

Code: Alles auswählen

# Load Hostfile
hostlist = {}
hostfile = file('Hosts.TXT')
server = hostfile.readline()
while server:
  hostlist[server.partition(':')[0]]=server.partition(':')[2]
  server = hostfile.readline()
hostfile.close()

print hostlist
Und das ist dann die Ausgabe:

{'29998': '127.0.0.1', '29999': '127.0.0.1\n'}
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

ConfigParser und XML halte ich für so eine Aufgabe einerseits nicht geeignet und andererseits overhead. Für sowas reicht eine einfache CSV Datei, wenn du csv.DictReader benutzt bekommst du auch gleich ein Dict heraus.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

" ".strip()
Ist was du suchst.

Zu ConfigParser: Du hast Key und Value Paare in einer Konfigurationsdatei. Was ist ein Dictionary? ;) Du musst dich ja nicht an die Syntax für Dictionary-Literale halten.

ConfigObj ist im Prinzip das gleiche wie ConfigParser nur ne Nummer größer.

Wenn die Datei händisch editierbar sein soll, dann würde ich dir allerdings zu den Config* raten. Das Format ist schliesslich bekannt (und sogar standardisiert ;))

P.S. Es heisst Pickle nicht Prickle.
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

Crady hat geschrieben: Damit das Programm aber konfigurierbar bleibt, möchte ich das Dictionary aus einer Knfigurationsdatei einlesen...
Sollte sich zB einfach mit JSON machen lassen..

PS. aber immer prüfen, was man ausführt ;-)
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Danke, cofi! So scheint es zu gehen:

Code: Alles auswählen

# Load Hostfile
hostlist = {}
hostfile = file('Hosts.TXT')
server = hostfile.readline()
while server:
  serv = server.strip(':\n')
  hostlist[serv.partition(':')[0]]=serv.partition(':')[2]
  server = hostfile.readline()
hostfile.close()

print hostlist
muss ich nun morgen in der Testumgebung noch ausprobieren - sollte aber klappen...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Das ist aber ziemlich umständlich. Eine Zeile hätte es auch getan ... :wink:

Code: Alles auswählen

hostdict = dict([zeile.strip().split(":") for zeile in open("hosts.txt","r")])
Wandelt hosts.txt mit dem Inhalt

Code: Alles auswählen

port1:IP1
port2:IP2
port3:IP3
port4:IP4
port5:IP5
um in

Code: Alles auswählen

{'port4': 'IP4', 'port5': 'IP5', 'port2': 'IP2', 'port3': 'IP3', 'port1': 'IP1'}
Ja, man sollte die Datei noch schließen.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Ohne das Rad neu zu erfinden gehts auch so:

Code: Alles auswählen

>>> from __future__ import with_statement
>>> import csv
>>> with open("hosts.txt", "rb") as file_obj:
...  new_dict = dict(row for row in csv.reader(file_obj, delimiter=":"))
... 
>>> new_dict
{'port4': 'IP4', 'port5': 'IP5', 'port2': 'IP2', 'port3': 'IP3', 'port1': 'IP1'}
>>> 
Ist vielleicht hier nicht unbedingt nötig, aber das ist nunmal ein CSV Format. Grade beim Zugriff auf Dateien sollte man sich nicht selbst irgendwas zurechtschnipseln, imho. Außerdem ist das leicht erweiterbar.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

str1442 hat geschrieben:Ist vielleicht hier nicht unbedingt nötig, aber das ist nunmal ein CSV Format. Grade beim Zugriff auf Dateien sollte man sich nicht selbst irgendwas zurechtschnipseln, imho. Außerdem ist das leicht erweiterbar.
Naja, das hängt aber auch davon ab, wie vertraut man mit den entsprechenden Modulen ist. Ich z.B. habe das csv-Modul noch nie benötigt, weiß nicht mehr darüber als dass es das gibt. Im vorliegenden Fall ist der Code zur Problemlösung (meine Fassung) in geschätzten 2 min fertig. Da empfindet man keine besondere Drang oder Notwendigkeit, sich zuvor mit einem neuen Modul zu beschäftigen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ich finde CSV auch zum Editiere für Nutzer eine Zumutung. Das ist nett für Übergabe von Daten, aber für Konfigurationen würde ich ConfigParser jederzeit vorziehen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

@Leonidas

Naja, per Editor und mit langen Zeilen schon, ist ja auch ein "Barebone" Format. Allerdings kann man zb auch OpenOffice Calc / Excel (wobei excel Microsoft mässig gern mal Mist zu bauen scheint) verwenden.

ConfigParser allerdings erfordert zwingend eine Sektion, die ja hier nicht gegeben ist. Könnte man "Hosts" nennen, wäre aber redundant.

@Numerix: Klar, deswegen habe ich ja drauf hingewiesen ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

str1442 hat geschrieben:Naja, per Editor und mit langen Zeilen schon, ist ja auch ein "Barebone" Format. Allerdings kann man zb auch OpenOffice Calc / Excel (wobei excel Microsoft mässig gern mal Mist zu bauen scheint) verwenden.)
Es ist aber eindeutig eine Konfigurationsdatei. Editierst du Konfigurationsdateien in Excel? Ist auch schlechter geeignet für Versionskontrolle etc.
str1442 hat geschrieben:ConfigParser allerdings erfordert zwingend eine Sektion, die ja hier nicht gegeben ist. Könnte man "Hosts" nennen, wäre aber redundant.
In dem Fall etwas, aber spätestens wenn weitere Parameter festgelegt werden sollen wird es nötig und daher halte ich es im Hinblick auf leichte Erweiterbarkeit akzeptabel. Eine Section hinzuzufügen ist definitiv weniger Overhead, als etwa XML vorschreibt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Kommt auf die Konfigurationsdatei an. Im hier vorliegenden Fall geht es ja nicht primär um Konfiguration, sondern um eine Zuordnung. Soll zwar auch von Hand editierbar sein, ist aber primär imho keine Konfiguration, denn Konfigurationen haben typischerweise keine Auflistungen, sonderen statische Namen, deren Wert man entsprechend setzt. Insofern verwende ich csv für Konfigurationen auch nicht. Konfigurationsdateien an sich sollten natürlich per Editor bearbeitbar sein, und solange die Zeilen einer csv Datei recht kurz bleiben, geht das auch.

Schlechter bei der Versionskontrolle: Das einzige was mir da einfallen würde wären recht lange "diff" Zeilen, aber XML und co sehen da auch nicht so schön aus.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

str1442 hat geschrieben:Schlechter bei der Versionskontrolle: Das einzige was mir da einfallen würde wären recht lange "diff" Zeilen, aber XML und co sehen da auch nicht so schön aus.
Ich bin mir nicht sicher, ob CSV dir die Reihenfolge der Einträge garantiert, also kann es da auch dazu kommen, dass die Datei komplett umsortiert wird, was bei Diffs eher blöd aussieht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Das CSV Modul funktioniert per Generator und gibt einem die Einträge von Anfang bis Ende linear zurück. Ansonsten dürfte es da eher keine Umsortierungen geben. Im Gegenteil, wenn man eine CSV Datei mit OpenOffice Calc editiert, werden die einzelnen Spalten ja auch geordnet dargestellt. Und per Editor funktionierts auch.
Crady
User
Beiträge: 18
Registriert: Freitag 31. Oktober 2008, 18:58

Vielen Dank, Euch allen!

Also meine Version - oder eben die Kompakte von Numerix funktionieren ganz gut...

Muss nur den Port noch in eine Integer wandeln, da ich mich mit einem String nicht verbinden kann.

@Leonidas: (Edit...)

Der ConfigParser ist zwar ganz schön - wenn man nur einen Wert braucht... Wenn ich in meiner Config.ini z.B. eingebe:

Code: Alles auswählen

[Hosts]
Hosts = {port:'IP', port:'IP',....,port:'IP'}
Dann kann ich das (in meinen Versuchen jedenfalls) nur als einen kompletten String auslesen - nicht als Dictionary...

Wenn ich z.B.

Code: Alles auswählen

[Namen]
Namen: Hans, Peter, Uwe
Auslese und dann in einer FOR Schleife drucke bekomme ich:

Code: Alles auswählen

H
a
n
s
,

P
e
t
e
r
,

U
w
e
Statt:

Code: Alles auswählen

Hans
Peter
Uwe
Naja... wie dem auch sei, DIESES Problem ist nun erstmal gelöst :)

Nun mache ich mich mal an einen GUI für die Eingaben... da muss ich aber noch was in meinem Viseo2Brain ansehen bzw. mein Buch weiterlesen :)
Zuletzt geändert von Crady am Sonntag 2. November 2008, 16:17, insgesamt 1-mal geändert.
Antworten