Seite 1 von 2

Verfasst: Samstag 10. März 2007, 19:15
von Markus12
Wieso gibt pickle.dump denn None zurück?

Ich mach das nur weils mir Spaß macht und weil ich dadurch Pyton besser lerne. :wink:

Verfasst: Samstag 10. März 2007, 19:53
von Dill
pickle.dump(variable, datei) schreibt eine python variable in eine datei.
die funktion hat keinen rückgabewert - was soll sie auch zurückgeben, ausser evtl. einen status, und den willst du sicher nicht in deinem dict stehen haben.

anders pickle.load(datei), es liest eine (oder mehrere) variablen aus einer datei.
rückgabewert ist die gelesene variable. hast du ja auch richtig verwendet.

dann bring das programm mal zum laufen, viel glück :)
wenn du dann immernoch spass am programmieren hast, wäre es zeit für ein refactoring :wink:

Verfasst: Samstag 10. März 2007, 23:23
von Masaru
Huiuiui,

gerade wenn Du Python programmieren lernen möchtest, mein Tipp wäre das Du Dich dennoch vorher mit ein paar Dingen wie:
- Objektorientierung (u. solche in Python)
- Model-View-Control Konzept
- Modularisierung (u. solche in Python)

auseinander setzen solltest.

Du möchtest eine kleine grafische Oberfläche gestalte, welches eigentich schon ein recht gutes Programm darstellen könnte, nutzt aber Techniken des einfachen Scriptens.

Python kann mehr als sequentiell aus einer Datei Funktionsaufrufe durchzuführen und Methodendefinitionen zuzulassen.

Du könntest Dein Script in mindestens in zwei Klassen, wenn nicht sogar mehrere Module zerlegen:
- Speicher (eine Klasse, welche Zugriffsmethoden wie "spechere_satz, lese_satz, update_satz, hole_liste, etc.")
- Oberfläche (als Klasse, um schön die Klassenvariablen anstellen der bösen gobals nutzen zu können)
- etc.

Wenn Du für Deinen einen einheitlichen Methodenumfang für die Oberflächenklasse definierst, wäre es für Dich z.B. später auch kein Problem anstelle des Picklens in eine Datei mit einer Datenbank zu arbeiten.

Einfach eine Klasse schreiben, welche die gleichen Funktionalitäten anbietet und das Verhalten auf den Datenbankadapter umbricht .. voilla.

Viel Spass auf jeden Fall noch beim Python lernen :D

Verfasst: Sonntag 11. März 2007, 00:56
von Dill
ich denke nicht, dass es sinnvoll ist sich mit diesen ganzen konzepten auseinander zu setzen, bevor man es nicht mindestens einmal "falsch" gemacht hat.

wenn du einem einsteiger gleich das MVC um die ohren schlägst bekommt ders ja mit der angst zu tun :wink:

Verfasst: Montag 12. März 2007, 14:24
von Masaru
@ Markus

Vielleicht hilft dir noch folgende Hilfestellung beim Aufbau und der Optimierung deines Programmes.

In Python ist es möglich "Objektorientiert" zu programmieren. Hier im Forum gibt es einige gute Posts, die sich damit beschäftigen.

Mein Tipp wäre die Unterteilung Deiner Anwendung in sagen wir einmal mindestens zwei Klassen.
  • - grafische Oberfläche
    - Dateizugriffe
Der Grund - oder das Ziel - ist es, dass Du in einem Objekt u.a. auf sogenannten Klassenmethoden und -attribute zugreifen kannst, welche Dir bei der Einbindung der Button-Methoden und z.B. Färbungsmethoden sehr hilfreich sein können.
Ebenfalls erlaubt es eine klare Trennung zwischen der reinen Oberfläche und dem Datei-Pickle-Speicher, wodurch das Entwickeln und Testen für Dich um einiges leichter und durchschaubarer werden sollte.

Hier z.B: eine solche Oberflächenklasse:

Code: Alles auswählen

from Tkinter import*

# Definition der Farben durch Konstanten (Vorteil: wenn Du einmal die 
# Farbe aendern moechtest, musst Du nicht alle Strings anpassen, sondern
# nur diese Konstanten.

FARBE_LABLE_NORMAL  = 'white'
FARBE_LABLE_WARNUNG = 'red'


class TelefonBuch(Tk): 
    """Grafische Oberflaeche und Programmlogik"""

    def __init__(self):
        Tk.__init__(self)

        self.title('Telefonlisten Verwaltung')
        
        frame = Frame(self, bg='PaleGreen', height=400, width=400)
        frame.pack()

        self.__eintrage = 0  # anstelle mit "globals" kannst Du viel effektiver die Variable so als Klassenvariable nutzen

        self.__load_statische_elemente(frame)  
        self.__load_dynamische_elemente(frame) 
        
        self.__mein_daten_speicher = MeinDatenSpeicher('mydict.pkl') # die nachste von mir angesprochene Klasse ;)
        # ....

    def __load_statische_elemente(self, frame):
        l_ueberschrift = Label(frame, bg='PaleGreen', font=('Arial',30,'bold'), text='Telefonliste')
        l_ueberschrift.place(x=90, y=20)
        # ...
        
    def __load_dynamische_elemente(self, frame):
        self.__eingabe_name = Entry(frame, width=20, font=('Arial',12,'bold'))
        self.__eingabe_name.place(x=50, y=140)

        self.__eingabe_nummer = Entry(frame, width=20, font=('Arial',12,'bold'))
        self.__eingabe_nummer.place(x=50, y=23
        #...

    def __get_name_nummer(self)
        """Liefert die Werte der Felder Name und Nummer zurueck,
        und faerbt bei Fehlerhaften Eingaben eventuell """
        name = self.__eingabe_name.get()
        nummer = self.__eingabe_nummer.get()
        if not name:
            self.__eingabe_name.config(bg=FARBE_LABLE_NORMAL)
        else:
            self.__eingabe_name.config(bg=FARBE_LABLE_WARNUNG)
        if not nummer:
            self.__eingabe_nummer.config(bg=FARBE_LABLE_WARNUNG)
        else:
            self.__eingabe_nummer.config(bg=FARBE_LABLE_NORMAL)
        return name, nummer
        
    def self.__neu(self):
        """Methode hinter dem Button 'neu'"""
        name, nummer = self.__get_name_nummer()
        # ...
        if name in self.__mein_daten_speicher.liste_alle_namen():
            # ...
        if nummer in self.__mein_daten_speicher.liste_alle_nummern():
            # ...
        erfolgt = self.__mein_daten_speicher.schreibe_daten(name, nummer)
        if erfolgt:
            return True
        else:
            self.__faerbe_fehler(
              "Konnte '%s' mit Nummber '%s' nicht eintragen." % (name, nummer))
        
    # ...
und hier beispielhaft noch für den Zugriff auf den Datei-Pickle-Speicher:

Code: Alles auswählen

import pickle
import os

class MeinDatenSpeicher(object):
    """Datenspeicher Klasse, um auf Daten in einer Datei zuzugreifen,
    bzw. letztendlich persistent zu halten"""
    
    def __init__(self, dateipfad):
        self.__datei_pfad = dateipfad
        self.__datei_objekt = None
        self.__speicher_inhalt = None
        
        self.__lade_speicher()
        
        self.__aktualisiere_speicher()
        
    def __lade_speicher(self):
        if not os.path.isfile(self.__datei_pfad):
            self.__datei_objekt = open(self.__datei_pfad, 'w+') 
        self.__aktualisiere_speicher()
        
    def __aktualisiere_speicher(self):
        self.__speicher_inhalt = pickle.load(self.__datei)
    
    def schreibe_daten(self, name, nummer):
        self.__aktualisiere_speicher()
        
        if name in self.__speicher_inhalt.keys():
            return False
        if nummer in self.__speicher_inhalts.values():
            return False
        return True
        
    def liste_speicher(self):
        self.__aktualisiere_speicher()
        return self.__speicher_inhalt
Ein schönes Beispiel für eine solche konzeptionelle Unterteilung zwischen Darstellung mit Logik und der Datenebene, ist dieses Codesbeispiel von Gerold um [wiki=CPU_Anzeige_(win32)]CPU-Auslastung anzuzeigen[/wiki].

Weicht ein wenig alles von deiner ursprünglichen Fragestellung bezüglich des Datei-Picklens ab ... aber ... glaub mir, so hättest Du es ein wenig einfacher und überschaulicher (gerade auch in Bezug auf das Entwickeln, Testen, Nachfragen im Forum, etc. bezüglich der Pickle-Speicher-Komponente).

Gruß,
>>Masaru<<

Verfasst: Montag 9. April 2007, 21:27
von Markus12
Cool, das ihr mir alle geholfen habt!

@Masaru:

Danke für die Hilfestellung!

Programmiert ihr eig. alle mit Klassen?
Ich hab schon verstanden, das es Vorteile hat im Bezug auf das 'global',
aber im Prinzip ist das doch so leichter, wenn man das nicht mit Klassen macht oder?

Code: Alles auswählen

def schreibe_daten(self, name, nummer):
        self.__aktualisiere_speicher()
Sonst muss man doch immer wie hier die Nummer und den Namen angeben?
Das kommt mir ein bisschen vor, als würde das zu allgemein sein, weil man das immer anders benutzt.
Klassen dachte ich wären sinnvoll wenn man Module schreibt.

Naja^^

Verfasst: Montag 9. April 2007, 22:43
von Leonidas
Markus12 hat geschrieben:Programmiert ihr eig. alle mit Klassen?
Ich programmiere nur mit Klassen, wenn das Problem sich durch den Einsatz von Klassen vereinfachen lässt. Jedes Problem mit Klassen zu lösen ist sinnlos und macht nur zusätzliche Arbeit.
Markus12 hat geschrieben:Klassen dachte ich wären sinnvoll wenn man Module schreibt.
Das hat doch nichts miteinander zu tun, außerdem ist jede Python-Datei automatisch auch ein Modul.

Verfasst: Montag 9. April 2007, 22:54
von DaSch
also ich als Python Anfänger kann nur sagen man sollte an die Funktionen Klassen Module langsam herangehen.

Ich hab meine erste Sachen nur als Skript geschrieben, dann hab ich da Funktionen eingefügt und langsam mach ich mich daran auch noch verschiedene Klassen zu machen. Ich find auch man sollte sich da langsam herantasten. Also bevor du mit Klassen anfängst einfach erstmal bisschen was mit Funktionen ausprobieren und dann können die Klassen drankommen.

Verfasst: Dienstag 10. April 2007, 13:26
von Markus12
ok :D

Ich hab mir jetzt auch ein Python Buch gekauft: "Objektorientierte Programmierung mit Python" in der alles ganzganau auf fast 700 Seiten beschrieben wird und es dann langsam auch auf Klassen drafzuläuft