Wie Text aus einer Datei mit Python auslesen?

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.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Leonidas hat geschrieben:
mocca hat geschrieben:ich möchte nun ja aber dem namen "exclude" alles zuweisen, wass eben ungleich 'thumb' ist.
Also auch meine Badeente und den Hund des Nachbarn?

Sorry, aber woher soll denn das Programm wissen was es denn zuweisen soll? Du musst einem Programm sagen was es machen soll und nicht was es nicht machen soll.

Im übrigen schließe ich mich Lunar an - du solltest dringend ein Tutorial oder sogar mehrere Bücher konsultieren.
ja, auch deine badeente, wenn sie es irgendwann mal in eine meiner nfos schafft.

die docs von etree sagen doch ganze eindeutig, dass getiterator per default alle sucht. sprich, wenn ich getiterator() benutze, dann sucht er ALLE tags, egal wie sie heissen.
genau das soll es ja auch weiterhin tun, nur eben mit der ausnahme EINES bestimmten tags.
sprich, statt zu definieren, was er suchen soll, will ich ihm sagen, was er nicht suchen soll.

denn per default sucht er ja schon alles.

ums mal non-python zu schreiben, soll er letztlich "* ausser thumb" suchen.
lunar

Ah, jetzt verstehe ich dich. Nun, die Methode ".getiterator()" unterstützt keine Negation, sondern nur die Angabe eines Tags, um die Suche einzugrenzen. Was du möchtest, ist mit ".getiterator()" allein nicht möglich.

Du kannst also entweder ".getiterator()" jeweilfs für jeden Tag, den du bearbeiten möchtest, aufrufen, insgesamt also mehrmals hintereinander. Oder du nutzt ".findall()" oder ".getchildren()" und filterst ungewollte Tags mittels normaler If-Ausdrücke heraus.

Für komplexere XML-Abfragen gibt es mit XPath und XQuery auch eigene Abfragesprachen. Das ElementTree-Modul der Standardbibliothek allerdings unterstützt das nicht, dafür musst du auf lxml zurückgreifen.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

lunar hat geschrieben:@HerrHagen:
Markup sollte man mit entsprechenden Parsern lesen, String-Manipulation ist fehleranfällig und wenig robust.
XML ist ja eh magisch... ;)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

danke lunar.

hab ich mir schon gedacht, dass das so nicht geht.
na dann werd ich einfach alle einzeln auslesen :)
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

jetzt bräucht ich nur noch ne lösung für das problem mit dem übergeben des textes aus name.text

aktuell bin ich soweit, dass es ausgelesen wird und mir im programm auf dem bildschirm ausgegeben wird

Code: Alles auswählen

		if os.path.exists(tvshownfo):
			if currPlay is not None:
				tree = etree.parse(tvshownfo)
				for actor in tree.findall('//actor'): 
					for name in actor.getiterator('name'):
						print '%s: %s' % (name.tag.capitalize(), name.text)
						tlist.append(ServiceInfoListEntry("Name: ", name.text))
						self["NameScreen"].setText("Name: " + name.text)
problem ist nur, dass hierbei halt nur der letzte "name" ausgegeben wird. "print name.text" gibt nach wie vor alles aus, aber ich muss es per "self["NameScreen"].setText" machen (programm erfrdert es so).

gibts also eine möglichkeit name.text in eine kompatible form zu bringen, damit self.setText das vollständig ausgeben kann?

sprich:

ist
Name: Moran Atias
soll
Name: Arlene Tur
Name: Jocko Sims
Name: Luis Chavez
Name: Nick E. Tarabay
Name: Moran Atias
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

kriegs leider nicht alleine hin :(

ist es denn überhaupt möglich?
oder muss ich ein anderes modul nehmen, wenn ich möchte, dass er mir alle namen anzeigt und als objekt in einem neuen namen speichert?

denn "print name.text" kann ich schlecht weiterreichen :(

oder gibts eine möglichkeit name.text irgendwie so zu wandeln, dass ich einen namen erhalte, in dessen objekt eben alle schauspielernamen drin stehen?
BlackJack

@mocca: Du darfst halt nicht jeden Namen einzeln setzen und damit den alten überschreiben, sondern musst die sammeln, am Ende zu *einer* Zeichenkette zusammen setzten und *die* dann setzen.

Wenn Du nicht weisst welchen Datentyp man dafür nimmt, oder mit welchen Zeichenkettenmethoden man die gesammelten Namen verbindet, solltest Du mal das Tutorial in der Python-Dokumentation durcharbeiten.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

ok, ja, das weiss ich wirklich nicht :(

ich sehe nur, dass in name.text ja alle informationen drin sind. denn ein print name.text gibt ja die komplette "liste" aus.

also muss ich irgendwie den "inhalt" von name.text sammeln?

welches der 80 tutorials würdest du mir dazu empfehlen?

und nur damit ich am ende nicht trotzdem das falsche probiere, wie heisst nur das, was in name.text steht? ist es eine liste, ein iterator, eine zeichenkette, Dictionary.....
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

mocca hat geschrieben:welches der 80 tutorials würdest du mir dazu empfehlen?
Es gibt nur das einzig wahre.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

mocca hat geschrieben:und nur damit ich am ende nicht trotzdem das falsche probiere, wie heisst nur das, was in name.text steht? ist es eine liste, ein iterator, eine zeichenkette, Dictionary.....
``type()`` hilft.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

also ein string.
hmm.

bringt mich noch nicht weiter, denn ich muss irgendwie beim einlesen der daten schon dafür sorgen, dass er jeden gefundenen eintrag als objekt an einen eigenen namen weiterreicht.
nur wie weiss ich noch nicht.

es heisst ja bei findall() : "Returns a list or iterator containing all matching elements, in document order."

also müsste ich hier was ändern, damit er eine richtige liste erzeugt.
aber er erzeugt ja automatisch die name.text, wenn ich das richtig verstehe und darin ist nur der letzte gefundene eintrag gespeichert, weil vermutlich alle vorher gefundenen überschrieben wurden.

Code: Alles auswählen

        for actor in tree.findall('//actor'): 
                for name in actor.findall('name'):
                        print '%s: %s' % (name.tag.capitalize(), name.text)
aber ich sehe hier garnicht, dass eigentlich ein "name.text" erzeugt wurde. das wird also wohl im modul intern so gesetzt? kann ich dann unter verwendung dieses moduls überhaupt mein ziel erreichen?
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

sorry, ihr sagt immer "lies das tutorial", aber dann gehe ich im tutorial mal die grundbegriffe durch. schön. wo steht nun, dass name.text erzeugt wurde?

ich bin elementtree docs durchgegangen und konnte jetzt nur rausfinden, dass es mir den ersten oder alle einträge finden kann.
ja, schön, aber ich will nicht nur den ersten, sondern alle. aber wenn es alle findet, dann überschreibt es auch alle miteinander.

da muss es ja also einen kniff geben, wie man ihm sagt, er soll eben jedes einzeln speichern.

also hab ich mal bei den iterators geschaut. dort gibt es ja next(). aber das krieg ich irgendwie nicht in die drei zeilen rein. kommt nix bei raus.

das tutorial ist also toll, wenn man eine funktion eines moduls nachschauen will, aber nun weiss ich ja schon, welche funktion ich benutzen will, nur find ich einfach nicht, wie ich dafür sorge, dass dessen output auch in einer für mich brauchbaren form erscheint.

frustrierend :cry:

mir ist klar, dass ihr denkt, ich bin nur zu faul. vielleicht auch zu blöd.
aber ich bin hier echt fleissig am schreiben und lesen und habe ja die meisten sachen auch alleine hingekriegt (den rest des programms meine ich damit).
aber jetzt kann ich zwar mit hilfe des etree alles auslesen, was ich will, denn die syntax hab ich nun glaube ich verstanden, aber der output ist nicht zu gebrauchen.
:evil:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was genau liefert Dir dieser Code als Ausgabe?

Code: Alles auswählen

        for actor in tree.findall('//actor'): 
                for name in actor.findall('name'):
                        print '%s: %s' % (name.tag.capitalize(), name.text)
Und dann beschreib doch noch mal bitte, was Dich daran stört bzw. was Du haben willst.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Hyperion hat geschrieben:Was genau liefert Dir dieser Code als Ausgabe?

Code: Alles auswählen

        for actor in tree.findall('//actor'): 
                for name in actor.findall('name'):
                        print '%s: %s' % (name.tag.capitalize(), name.text)
Und dann beschreib doch noch mal bitte, was Dich daran stört bzw. was Du haben willst.
In der console bringt es
Name: Arlene Tur
Name: Jocko Sims
Name: Luis Chavez
Name: Nick E. Tarabay
Name: Moran Atias
wenn ich aber anschliessend

Code: Alles auswählen

print name.text
eingebe kommt
Name: Moran Atias
ich möchte, dass ein name erzeugt wird, der bei dem aufruf

Code: Alles auswählen

print name
das hier ausgegeben wird

Code: Alles auswählen

Name: Arlene Tur 
Name: Jocko Sims 
Name: Luis Chavez 
Name: Nick E. Tarabay 
Name: Moran Atias
lunar

Nutze eine Liste, an die du bei jedem Schleifendurchlauf die gefundenen Werte anhängst. Vor der Ausgabe fügst du diese Liste dann mit den Methoden zur Verarbeitung von Zeichenketten zusammen. Das solltest du aber wirklich alleine hinbekommen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Code: Alles auswählen

In [1]: players = ["Shaun Murphy", "Ronnie O'Sullivan", "Steven Hendry"]

In [2]: for player in players:
   ...:     print player
   ...:
   ...:
Shaun Murphy
Ronnie O'Sullivan
Steven Hendry

In [3]: print player
------> print(player)
Steven Hendry

In [4]: print players
------> print(players)
['Shaun Murphy', "Ronnie O'Sullivan", 'Steven Hendry']
Du suchst Listen!

Genau das hast Du bei Dir quasi auch. "player" wird in jedem Schleifendurchlauf immer neu gebunden; daher ist nach der Schleife der letzte Name aus der Liste "players" noch an player gebunden.

Du musst also in Deiner Schleife einfach jedes Element in eine neue, vor der Schleife definierte Liste packen.

Auch wenn es nervt: Du solltest Dir wirklich mal das Tutorial angucken. Listen sind nun einmal essentiell wichtig!

OT: Ist das "'" ein netter "Bug" im Highlighting Modul?
lunar

Hey, schaut da jemand auch die WM in Shefield?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:OT: Ist das "'" ein netter "Bug" im Highlighting Modul?
Wo?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

lunar hat geschrieben:Hey, schaut da jemand auch die WM in Shefield?
Aber Hallo ;-) Aber auch sonst gerne!

@Leonidas: Zeile 9 ... nach O'Sullivan wird alles rot - er erkennt das dort wohl als "String-Start-Token".
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

und ich verpass snooker, weil ich so nen käse nicht gebacken krieg :D

naja, wenn ich darf, halt ich euch auf dem laufenden, auch wenns mich vielleicht in ein NOCH schlechteres licht stellt ;)

dachte ich lasse ihn einfach bei jedem durchgang einen weiteren eintrag in eine liste anhängen. aber entweder hab ichs falsch gemacht, oder der gedanke war falsch.

Code: Alles auswählen

namelist = ""
if os.path.exists(tvshownfo):
        tree = etree.parse(tvshownfo)
        for actor in tree.findall('//actor'): 
                for name in actor.getiterator('name'):
                        namelist.append(name.text)
                        print '%s: %s' % (name.tag.capitalize(), name.text)
kommt nämlich
AttributeError: 'str' object has no attribute 'append'
also mal weiter im tutorial suchen :)
Antworten