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.
lunar

mocca hat geschrieben:kann man also nicht mit einem einfach "tag != 'thumb'" oder ähnlichem machen, sondern ich müsste alle erlaubten tags definieren?
Natürlich kannst du auch Negationen ala "tag != 'thumb'" verwenden. Wie kommst du denn darauf, dass das nicht funktionieren würde? Außerdem ist child.text keine "Liste". Die Liste kannst du allenfalls selbst erzeugen.

Ich denke, dir fehlt noch einiges an Grundwissen. Weder kennst du die grundlegenden Datenstrukturen, noch scheinst du bei der Formulierung Bedingungen firm zu sein. Du bist dir ja anscheinend nicht mal im Klaren darüber, was eine Zuweisung an einer bestimmten Stelle des Programms bewirkt. Hast du denn das Tutorial durchgearbeitet?
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

weil

Code: Alles auswählen

exclude != 'thumb'
tree = etree.parse(tvshownfo) 
for actor in tree.findall('//actor'): 
    for child in actor.getiterator(exclude): 
        print '%s: %s' % (child.tag.capitalize(), child.text)
zu
exclude != 'thumb'
NameError: name 'exclude' is not defined
führt.

ok, offensichtlich darf man exclude nicht einfach so banal definieren, deshalb ja meine frage danach.
hatte gehofft, dass das letztlich "exclude = 'alles was nicht dem string "thumb entspricht " entsprechend würde.

denn man gibts ja nicht an, was getiterator überspringen soll, sondern alles was er lesen soll.

ich muss also "alles ausser 'thumb'" als die variable exclude definieren.

p.s.: damit ich das zukünftig nicht falsch formuliere: ist exclude hier nun als "variable" zu bezeichnen oder als "name" oder als was? im tutorial wird da z.b. gesagt
beispiel="das ist ein beispiel" weist dem Objekt "das ist ein Beispiel" den Namen beispiel zu"

p.p.s.: wenn child.text keine "liste" ist, wie wäre die korrekte bezeichnung dafür? "element" oder "tree element"?


EDIT: ok, offensichtlich will ich keine "liste", denn wenn ich

Code: Alles auswählen

Actors = list(child.text)
mache kommt eine liste der buchstaben raus.
lunar

Wenn es dich verwundert, dass ein nicht definierter Name nicht definiert ist, dann solltest du dringendst das Tutorial durcharbeiten! Dir fehlt einiges an Grundwissen, und ich für meinen Teil habe auch weder Zeit noch Lust, dir die Grundlagen über Datenstrukturen, Datentyp, Bedingungen, Zuweisungen, etc. beizubringen. Nichts für ungut :)

Python hat keine Variablen, das ist ein Konzept aus kompilierten Sprachen, bzw. solchen, die zwischen Stack und Heap unterscheiden. Python bindet Objekte an Namen.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

ok, danke schön. dann ist es also ein name.

mich hat es nicht verwundert, nur normalerweise kann ich ja dem namen "exclude" das objekt "'thumb'" zuweisen.
das funktioniert ja auch.
ich möchte nun ja aber dem namen "exclude" alles zuweisen, wass eben ungleich 'thumb' ist.
wie muss dafür aber die syntax aussehen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
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.
Antworten