Fehlermeldung OOP

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
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Ich versuche gerade eine Notizverwaltung zu schreiben. Dazu folgender Code:

Code: Alles auswählen

import os.path
from datetime import datetime


class Notiz(object):

    def __init__(self, titel, datum, inhalt):
        self.titel = titel
        self.datum = datum
        self.inhalt = inhalt

    def __str__(self):
        return "%s\n%s" % (self.titel, self.inhalt)


class NotizbuchDB(object):

    def __init__(self, notizen):
        self.notizen = notizen

    def notiz_anlegen(self, neue_notiz):
        self.notizen[neue_notiz.titel] = neue_notiz


class Controller(object):

    def __init__(self):
        self.notizen = self.notizen_laden
        self.notizbuch = NotizbuchDB(self.notizen)

    def notizen_laden(self):
        self.notizen = {}

    def neue_notiz_anlegen(self):
        titel = raw_input("Titel: ")
        inhalt = raw_input("Notiz: ")
        datum = datetime.now

        neue_notiz = Notiz(
            titel, datum, inhalt
        )

        self.notizbuch.notiz_anlegen(neue_notiz)


def main():
    control = Controller()
    control.neue_notiz_anlegen()

if __name__ == '__main__':
    main()
Und diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "notizen.py", line 54, in <module>
    main()
  File "notizen.py", line 51, in main
    control.neue_notiz_anlegen()
  File "notizen.py", line 46, in neue_notiz_anlegen
    self.notizbuch.notiz_anlegen(neue_notiz)
  File "notizen.py", line 22, in notiz_anlegen
    self.notizen[neue_notiz.titel] = neue_notiz
TypeError: 'instancemethod' object does not support item assignment
Warum kommt diese Fehlermeldung?
BlackJack

@Xfd7887a: Das steht da doch eigentlich superdeutlich. Du versuchst auf einer Methode einen Indexzugriff. Was denkst Du denn was `self.notizen` an der Stelle für einen Wert hat? Lass Dir den doch mal vorher ausgeben. Und dann verfolge zurück wo der her kommt.
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Habe das Problem gefunden, danke :D.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Krass, wie man es schafft, eine so simple Aufgabe mit einem so komplizierten Entwurf zu realisieren. :twisted:
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Xfd7887a: das Problem ist, dass »notizen_laden« nichts in »Controller« zu suchen hat, und damit auch »notizen« da fehl am Platz ist. Zeile 37 solltest Du Dir auch nochmal anschauen.
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Ich habe ein neues Problem:

Code: Alles auswählen

class Notiz(object):
   ...
    def __str__(self):
        return "%s\n%s" % (self.titel, self.inhalt)

class NotizbuchDB(object):
   ...
    def __str__(self):
        for eintrag in self.notizen:
            print eintrag

class Controller(object):
   ...
    def notizen_anzeigen(self):
        print self.notizbuch

Code: Alles auswählen

Traceback (most recent call last):
  File "notizen.py", line 55, in <module>
    main()
  File "notizen.py", line 52, in main
    control.notizen_anzeigen()
  File "notizen.py", line 46, in notizen_anzeigen
    print self.notizbuch
TypeError: __str__ returned non-string (type NoneType)
__str__ return doch einen String, oder nicht?
BlackJack

@Xfd7887a: Nein die Methode gibt `None` zurück, weil am Ende von Methoden quasi ein implizites ``return None`` steht. Die Methode muss eine Zeichenkette an den Aufrufer *zurück*geben, und nicht irgenwas mit ``print`` *aus*geben.
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Habe mein Script jetzt erweitert:

Code: Alles auswählen

from time import localtime
from pickle import load, dump
import os.path


class Notiz(object):

    def __init__(self, titel, datum, inhalt):
        self.titel = titel
        self.datum = datum
        self.inhalt = inhalt

    def __str__(self):
        return "%s\n%s" % (self.titel, self.inhalt)


class NotizbuchDB(object):

    def __init__(self, notizen):
        self.notizen = notizen

    def notiz_anlegen(self, neue_notiz):
        self.notizen[neue_notiz.titel] = neue_notiz

    def notiz_loeschen(self, titel):
        del self.notizen[titel]

    def notiz_bearbeiten(self, titel):
        self.notizen[titel].inhalt = inhalt

    def notiz_suchen(self, titel):
        if self.notizen[titel]:
            print self.notizen[titel]
        else:
            print "Notiz nicht gefunden!"

    def anzeigen(self):
        for eintrag in self.notizen:
            print eintrag


class Controller(object):

    def __init__(self):
        self.notizen = self.notizen_laden()
        self.notizbuch = NotizbuchDB(self.notizen)

    def notizen_laden(self):
        if os.path.isfile("notizen.txt"):
            with open("notizen.txt") as datei:
                notizen = load(datei)
            return notizen
        else:
            return {}

    def notizen_speichern(self):
        with open("notizen.txt", "w") as datei:
            dump(self.notizen, datei)

    def neue_notiz_anlegen(self):
        titel = raw_input("Titel: ")
        inhalt = raw_input("Notiz: ")

        self.notizbuch.notiz_anlegen(
            Notiz(titel, localtime(), inhalt)
        )

    def notiz_loeschen(self):
        titel = raw_input("Titel: ")
        if raw_input("Notiz wirklich loeschen? ") == "ja":
            self.notizbuch.notiz_loeschen(titel)

    def notiz_aktualisieren(self):
        titel = raw_input("Titel: ")
        self.notizbuch.notiz_bearbeiten(titel)

    def notiz_suchen(self):
        titel = raw_input("Titel: ")
        self.notizbuch.notiz_suchen(titel)

    def notizen_anzeigen(self):
        self.notizbuch.anzeigen()


def main():
    control = Controller()

    menue = [
        ["Notizen anzeigen", control.notizen_anzeigen()],
        ["Neue Notiz", control.neue_notiz_anlegen()],
        ["Notiz loeschen", control.notiz_loeschen()],
        ["Notiz bearbeiten", control.notiz_aktualisieren()],
        ["Notiz suchen", control.notiz_suchen()]
    ]

    while True:
        for index, item in enumerate(menue, 1):
            print "{}  {}".format(index, item[0])

        auswahl = int(raw_input("> ")) - 1
        menue[auswahl][1]()

    control.notizen_speichern()

if __name__ == '__main__':
    main()
Jetzt startet das Programm mit der Ausgabe von "Titel:" und erwartet eine Eingabe. Wieso? Sollte es nicht eigentlich das Menü anzeigen?
BlackJack

@Xfd7887a: In `menue` müsstest Du den Text und die jeweils dazugehörige Methode speichern, Du rufst die Methode stattdessen aber auf und speicherst damit deren *Rückgabewerte* in der Struktur. Bei ``control.notizen_anzeigen()`` sieht man davon noch nichts weil noch keine Notizen da sind, aber in der nächsten Zeile rufst Du die Methode zum anlegen einer neuen Notiz auf, und die Fragt den Benutzer nach einem Titel.
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Stimmt, habe ich übersehen :D Danke
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Jetzt habe ich noch folgendes Problem:

Code: Alles auswählen

    def notiz_bearbeiten(self, titel):
        self.notizen[titel].inhalt = inhalt
Das scheint so nicht zu gehen. Wie kann ich eine Notiz bearbeiten?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

*Was* geht denn nicht? Was soll passieren und was passiert tatsächlich? Gibt es eine Fehlermeldung und wenn ja, welche? Wie lautet ggf. der Traceback? Die meisten von uns haben leider nur defekte Glaskugeln.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Xfd7887a hat geschrieben:Stimmt, habe ich übersehen :D Danke
Da musst Du das nächste mal aber das Tutorial genauer durcharbeiten ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

EyDu hat geschrieben:*Was* geht denn nicht? Was soll passieren und was passiert tatsächlich? Gibt es eine Fehlermeldung und wenn ja, welche? Wie lautet ggf. der Traceback? Die meisten von uns haben leider nur defekte Glaskugeln.
Folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "/Users/ich/Documents/Projekte/Notizverwaltung/src/notizen.py", line 107, in <module>
    main()
  File "/Users/ich/Documents/Projekte/Notizverwaltung/src/notizen.py", line 104, in main
    menue[auswahl][1]()
  File "/Users/ich/Documents/Projekte/Notizverwaltung/src/notizen.py", line 77, in notiz_aktualisieren
    self.notizbuch.notiz_bearbeiten(titel)
  File "/Users/ich/Documents/Projekte/Notizverwaltung/src/notizen.py", line 30, in notiz_bearbeiten
    self.notizen[titel].inhalt = inhalt
NameError: global name 'inhalt' is not defined
Warum ist "Inhalt" nicht vorhanden?
Xfd7887a
User
Beiträge: 135
Registriert: Montag 23. Juni 2014, 17:11

Habe das Problem gelöst. Wenn man keinen neuen Inhalt übergibt, kann man natürlich alten nicht überschreiben :D
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Fuer die Zukunft: Falls du zu einem Traceback keinen Code lieferst, koennen wir dir wahrscheinlich auch nur die Fehlermeldung vorlesen.
Antworten