Seite 1 von 1

Klassen & Dateien einlesen. Hilfe

Verfasst: Mittwoch 30. Dezember 2015, 15:15
von Nash404
Hallo Community,
Ich sitze jetzt seit 2 Tagen an einer eigentlich einfachen Aufgabe. Zumindest wurde mir das so gesagt...
Ich soll eine Text Datei einlesen lassen und die darin enthaltenen Namen der Klasse Person zuordnen. Quellcode habe ich beigefügt. Mein Problem ist ich kriege am Ende immer ein oder zwei Fehlermeldungen Und kann mir nicht erklären wieso.
Wenn mir jemand helfen könnte, wäre ich sehr dankbar.
Mit freundlichen Grüßen
Nash404

Code: Alles auswählen

class Person:
    def __init__(self, Vorname, Nachname, Geburtsdatum):
        self.Vorname = Vorname
        self.Nachname = Nachname
        self.Geburtsdatum = Geburtsdatum
    
     def setVorname(self, Vorname):
        self.Vorname = Vorname

    def setNachname(self, Nachname):
        self.Nachname = Nachname

    def setGeburtsdatum(self, Geburtsdatum):
        self.Geburtsdatum = Geburtsdatum


def addPerson(Vorname, Nachname, Geburtsdatum):
    p1 = Person(Vorname, Nachname, Geburtsdatum)
    return p1


def main():
    if os.path.isfile(sys.argv[1]) == False:
        print("Datei", sys.argv[1], "nicht gefunden")
        exit(0)
    with open(sys.argv[1]) as filetoread:
         lines_1 = filetoread.readlines()

       for i in range(len(lines_1))
        wordlist = re.split('\S', lines_1[i])
        tmp1 = wordlist[0]
        tmp2 = wordlist[1]
        tmp3 = wordlist[2]
        personenList = addPerson(tmp1.tmp2.tmp3)

        print(personenList.getVorname())
        print(personenList.getNachname())
        print(personenList.getGeburtsdatum())


if __name__ == '__main__':
    import sys
    import os
    import re
main()
Error:
Traceback (most recent call last):
File "/home/tim/PycharmProjects/untitled3/PersonenKlasse (namen.txt).py", line 50, in <module>
main()
File "/home/tim/PycharmProjects/untitled3/PersonenKlasse (namen.txt).py", line 41, in main
print(personenList.getVorname())
AttributeError: 'Person' object has no attribute 'getVorname'

Re: Klassen & Dateien einlesen. Hilfe

Verfasst: Mittwoch 30. Dezember 2015, 15:41
von BlackJack
@Nash404: Die Fehlermeldung ist doch recht deutlich: Die Einrückung der ``for``-Schleife passt zu keiner Einrückung der Zeilen davor und damit weiss Python nicht wann dieser Code ausgeführt werden soll.

Weitere Anmerkungen: Schau mal in den Style Guide for Python Code und passe die Schreibweise von Namen entsprechend an.

Die `addPerson()`-Funktion ist überflüssig, das ist effektiv ja nur ein anderer Name für `Person`.

Man vergleicht nicht mit literalen Wahrheitswerten. Das Ergebnis ist ja nur wieder ein Wahrheitswert, und den hatte man ja schon. Wenn man auf den gegenteiligen Wahrheitswert testen will, dann dreht man den einfach mit ``not`` um. So ein Test auf Dateiexistenz macht man aber auch nicht, denn das fällt ja sowieso auf wenn man versucht die Datei zu öffnen. Da würden dann auch all die anderen Varianten auffallen auf die Du nicht prüfst, zum Beispiel ob das Programm überhaupt die nötigen Rechte hat die Datei zu öffnen.

Wenn man schon explizit das Programm mit `exit()` beendet weil ein Fehler aufgetreten ist, dann sollte man *nicht* den Rückgabecode 0 verwenden, denn der steht per Konvention für „fehlerfrei durchgelaufen“.

Was soll die `_1` bei `lines_1`? Namen durchnummerieren, und dann auch noch prophylaktisch ist keine gute Idee. Wenn man anfängt Namen zu nummerieren, dann will man eigentlich bessere Namen verwenden oder eine Datenstruktur. Bei `tmp1` bis `tmp3` sollte man bessere Namen verwenden, nämlich welche die aussagen was der jeweilige Wert bedeutet. `vorname`, `nachname`, und `geburtsdatum` beispielsweise.

`personenList` ist ein falscher Name. Das ist keine Liste. Und selbst wenn, dann sollte der konkrete Datentyp nicht im Namen vorkommen, denn der kann sich im Laufe der Programmentwicklung ändern und dann muss man überall Namen anpassen oder hat falsche und irreführende Namen im Quelltext. Bei Containerdatentypen wird üblicherweise die Mehrzahl der Bezeichnung für ein einzelnes Element verwendet.

``for i in range(len(sequence)):`` ist in Python ein „anti pattern“. Man kann *direkt* über die Elemente iterieren, ohne den unnötigen Umweg über einen Indexwert.

`re` ist hier mit Kanonen auf Spatzen geschossen. Die `split()`-Methode auf Zeichenketten hat den gleichen Effekt.

Die Klasse hat keine `get*()`-Methoden und sie sollte die auch nicht bekommen! Greif direkt auf Attribute zu statt simple Getter und Setter-Methoden zu schreiben. Das ist Python und kein Java.

Importe gehören an den Anfang eines Moduls, damit man leicht sieht wo die Namen herkommen und wovon ein Modul abhängig ist.

Der `main()`-Aufruf gehört in den ``if __name__ …``-Block. Dafür ist diese Prüfung ja überhaupt da, um das Hauptprogramm davon abhängig zu machen ob das Modul importiert oder als Programm gestartet wurde.

Re: Klassen & Dateien einlesen. Hilfe

Verfasst: Mittwoch 30. Dezember 2015, 15:52
von BlackJack
Okay, mittlerweile hat sich die behauptete Fehlermeldung geändert, dafür gibt es jetzt an anderer Stelle einen Einrückungsfehler den Du eigentlich bekommen müsstest. Der Quelltext passt also nicht zur Fehlerbeschreibung. Die ``for``-Zeile von der letzten Fehlermeldung ist nun syntaktisch falsch, da fehlt ein ':' am Ende.

Zur aktuellen Fehlermeldung: Der Name ist ja auch tatsächlich nirgends definiert. Aber wie schon gesagt: triviale Getter/Setter schreibt man in Python sowieso nicht.

Re: Klassen & Dateien einlesen. Hilfe

Verfasst: Mittwoch 30. Dezember 2015, 18:19
von BlackJack
Ungetestet:

Code: Alles auswählen

import sys


class Person(object):

    def __init__(self, name, surname, birthday):
        self.name = name
        self.surname = surname
        self.birthday = birthday


def parse_line(line):
    name, surname, birthday = line.split()
    # 
    # TODO: Parse `birthday` into a `datetime.date` object.
    # 
    return Person(name, surname, birthday)


def parse_file(filename):
    with open(filename) as lines:
        return list(map(parse_line, lines))
 

def main():
    persons = parse_file(sys.argv[1])
    for person in persons:
        print(person.name)
        print(person.surname)
        print(person.birthday)

 
if __name__ == '__main__':
    main()

Re: Klassen & Dateien einlesen. Hilfe

Verfasst: Donnerstag 7. Januar 2016, 14:10
von Nash404
Erst einmal vielen Dank für die ausführliche Hilfestellung! Werde mich umgehen daran setzen und meine Fehler suchen.
Vielen Dank BlackJack!
Mit freundlichen Grüßen

Tim Paul