Hilfe Strellung

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
miles21
User
Beiträge: 3
Registriert: Freitag 13. August 2021, 18:31

Hallo,

ich bin gerade dabei Python zu lernen und bekomme diese Fehlermeldung:
Traceback (most recent call last):
File "C:/pythonProject/test.py", line 32, in <module>
testen()
File "C:/pythonProject/test.py", line 22, in testen
dateispeichern()
File "C:/pythonProject/test.py", line 17, in dateispeichern
print(i.toString())
AttributeError: 'str' object has no attribute 'toString'

Code: Alles auswählen

class Entry:
    def __init__(self, deutsch, englisch):
        self.deutsch = deutsch
        self.englisch = englisch

    def toString(self):
        if self.deutsch is None:
            return "Ende - End"
        return self.deutsch + " - " + self.englisch


eintraege = [Entry("Hallo", "Hello")]

def dateispeichern():
    f = open("Vokabeltrainer.txt", "a")
    for i in eintraege:
        print(i.toString())
        f.write(i.toString() + "\n")
    f.close()

def testen():
    dateispeichern()


if __name__ == "__main__":
    f = open("Vokabeltrainer.txt", "r")
    for i in f:
        eintraege.append(str(i.split(" - ")))
    f.close()
    for i in eintraege :
        print(i)
    testen()
    print("Fertig")

Kann mir eventuell jemand dies erklären?
Danke!
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Sehr gut: Die Schreibweise der Namen sieht auf den ersten Blick richtig aus und du verwendest einen Einstiegspunkt hinter dem if __name__ ... .

Verbesserungen: Verwende keine globalen Variablen. Das heißt: eintraege verschwindet von der Modulebene (also alles was nicht eingerückt ist) und alles was in dem if __name__ ... Block steht wandert in eine Funktion namens main() und der Block sieht dann wie folgt aus:

Code: Alles auswählen

if __name__ == "__main__":
    main()
Jetzt werden deine aufgerufenen Funktionen eintraege nicht mehr finden. Das ist gut, weil das ist dein Problem. eintraege hat nicht den Inhalt, den du annimmst. Das ist der große Mist bei globalen Variablen, deshalb verwendet man sie nicht. Du bist früh darüber gestolpert und kannst das verinnerlichen.
eintraege muss als Parameter an die Funktionen übergeben werden. Funktionen bekommen alles, was sie zum Arbeiten brauchen als Parameter und geben das Ergebnis mit return zurück. Dafür sind sie da.

Nicht für deinen Fehler verantwortlich: verwende open nur mit with
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Das `toString` sieht so aus, als ob Du versuchst, mit einem Java-Buch Python zu lernen. Methoden schreibt man wie Variablen komplett klein. Zudem gibt es eine spezielle Methode __str__, die man üblicherweise implementiert, wenn ein Objekt in einen String umwandeln werden soll.
Die spezielle Behandlung von `deutsch is None` sieht komisch aus.
Statt Strings mit + zusammenzustückeln benutzt man Formatstrings.
`eintraege` ist eine globale Variable, die nicht existieren sollte, alles was eine Funktion braucht, muß sie über ihre Argumente bekommen. Es ist auch komisch, dass da immer Fix ein Eintrag schon drinsteht, der dann durch weitere aus einer Datei Vokabeltrainer.txt ergänzt wird.
Dateien öffnet man innerhalb eines with-Statements und bei Textdateien gibt man immer auch ein Encoding an. Die Funktion `testen` ist überflüssig, da darin ja nur dateispeichern aufgerufen wird.
`dateispeichern` hängt immer wieder die selben Einträge an, die es kurz zuvor aus der selben Datei gelesen hat. Die Datei wächst also expotentiell.
`i` ist ein sehr schlechter Name für etwas, das in `eintraege` steht. `eintraege` ist eigentlich auch schon zu generisch, weil es sich ja offensichtlich um Vokabeln handelt.

Code: Alles auswählen

VOKABEL_DATEINAME = "Vokabeltrainer.txt"

class Vokabel:
    def __init__(self, deutsch, englisch):
        self.deutsch = deutsch
        self.englisch = englisch

    def __str__(self):
        if self.deutsch is None:
            return "Ende - End"
        return f"{self.deutsch} - {self.englisch}"


def vokabeln_schreiben(vokabeln):
    with open(VOKABEL_DATEINAME, "w", encoding="utf8") as file:
        for vokabel in vokabeln:
            print(vokabeln)
            file.write("{vokabeln}\n")

def vokabeln_lesen():
    vokabeln = []
    with open(VOKABEL_DATEINAME, encoding="utf8") as file:
        for zeile in file:
            vokabeln.append(str(zeile.split(" - ")))
    return vokabeln

def main():
    vokabeln = vokabeln_lesen()
    for vokabel in vokabeln:
        print(vokabel)
    vokabeln_schreiben(vokabeln)
    print("Fertig")

if __name__ == "__main__":
    main()
Jetzt zum eigentlichen Problem, der Zeile

Code: Alles auswählen

            vokabeln.append(str(zeile.split(" - ")))
Hier passieren sehr viele Dinge auf einmal, aber nicht das richtige.
Erst wird der String zeile an " - " getrennt, so dass Du eine Liste erhältst. Diese Liste wandelst Du in ihre Stringrepräsentation um (was außer für Debuggingzwecke nie sinnvoll ist) und steckst den String in die Vokabeln-Liste.
Die Vokabeln-Liste soll aber Objekte vom Typ Vokabel enthalten, im gesamten Code erzeugst Du aber nie solche Objekte. Deine Aufgabe ist es also noch, aus einem String der Form "Hallo - Hello\n" ein Objekt der Form Vokabel("Hallo", "Hello") zu machen.
miles21
User
Beiträge: 3
Registriert: Freitag 13. August 2021, 18:31

Danke zusammen, ich werde mal dies umschreiben und testen.

Dateien mit "with" zu öffnen und schreiben kannte ich noch nicht.

Wie gesagt bin ein Neuling in Python und mein Ursprung bzw. know how ist SQL.

PS. habt Ihr eventuelle eine Empfehlung zum Python programmieren lernen?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

PS. habt Ihr eventuelle eine Empfehlung zum Python programmieren lernen?
Das offizielle Python Tutorial:
https://docs.python.org/3/tutorial/

Oder die deutsche Übersetzung:
https://py-tutorial-de.readthedocs.io/de/python-3.3/
miles21
User
Beiträge: 3
Registriert: Freitag 13. August 2021, 18:31

rogerb hat geschrieben: Sonntag 15. August 2021, 11:32
PS. habt Ihr eventuelle eine Empfehlung zum Python programmieren lernen?
Das offizielle Python Tutorial:
https://docs.python.org/3/tutorial/

Oder die deutsche Übersetzung:
https://py-tutorial-de.readthedocs.io/de/python-3.3/
Vielen Dank, werde mal hier rein schauen.
Antworten