Seite 1 von 1

Daten in einer Klasse listen?

Verfasst: Mittwoch 9. Mai 2007, 22:55
von jo_hb
Hallo,
Also ich versuche mich grad an meinem ersten grösseren Programm mit Klassen, und ich wüsste gern ob es irgendwie möglich ist alle inhalte meiner Klasse als Liste auszugeben? Also so sieht's in etwa aus:

Code: Alles auswählen

class meineklasse:
  def __init__(self):
    self.a = ''
    self.b = ''
    self.c = ''
    self.d = ''
    self.e = ''
    self.f = ''
Das ganze fülle ich dann anderweitig mit Daten, und jetzt bräuchte ich diese Daten zurück, als Liste ['';'';'';'';'';''].

Also möglich ist das natürlich, aber ist es nicht vielleicht in Python auch schon eingebaut? :)

Oh, falls das eine triviale Frage war hab ich noch eine: De facto ist in meiner Klasse nämlich

Code: Alles auswählen

    self.c = EineAndereKlasse()
Diese andere Klasse besteht ihrerseits aus mehreren Variablen, etwa analog zu meineklasse. Und am besten wäre es nun wenn ich eine Liste bekommen könnte in der diese Daten (aus EineAndereKlasse) ebenfalls enthalten sind, also: ['';'';'';'';'';'';'';'';'';'';''].

Um das ganze noch etwas komplizierter zu machen: Es handelt sich bei den Daten in meinen Klassen nicht nur um Strings, sondern es sind auch int- und float-Zahlen dabei.

Hoffe es gibt einen halbwegs einfachen Weg das zu realisieren,
vielen Dank schonmal für eure Hilfe,
Jo

Verfasst: Donnerstag 10. Mai 2007, 08:19
von jens
Wie wäre es, wenn du einfach ein dict nimmst?

So in der Richtung:

Code: Alles auswählen

class meineklasse:
    def __init__(self):
        self.data = {}
        self.data["a"] = '...'
        self.data["b"] = '...'
        self.data["c"] = '...'
        self.data["d"] = '...'
        self.data["e"] = '...'
        self.data["f"] = '...'
    
    def print_liste(self):
        print self.data.values()

Verfasst: Donnerstag 10. Mai 2007, 08:53
von jo_hb
Hm, aber dann müsste ich doch bei allen Zuweisungen statt

Code: Alles auswählen

bla.a = 'test'
immer

Code: Alles auswählen

bla.data['a'] = 'test'
machen, oder? Gibt's sonst keine Möglichkeit an so eine Liste zu kommen?

Verfasst: Donnerstag 10. Mai 2007, 09:02
von BlackJack
Den Attributzugriff könnte man mit den entsprechenden Methoden abfangen und in das Dictionary umleiten. Aber ich denke das ist keine Lösung, weil ich mal annehme die Daten sollen in der Liste auch in einer bestimmten Reihenfolge stehen und Dictionaries sind ungeordnet.

Was genau versuchst Du denn da zu lösen?

Re: Daten in einer Klasse listen?

Verfasst: Donnerstag 10. Mai 2007, 09:06
von gerold
jo_hb hat geschrieben:und jetzt bräuchte ich diese Daten zurück, als Liste ['';'';'';'';'';''].
Hallo Jo!

Der Vollständigkeit halber:
Das ist eine Liste: ``['', '', '']``
Das ist keine Liste: ``[''; ''; '']``

Aus deinen Daten eine Liste zu generieren, ist nicht schwer.

Code: Alles auswählen

class MeineKlasseOriginal:
    def __init__(self):
        self.a = 'aa'
        self.b = 'bb'
        self.c = 'cc'

m = MeineKlasseOriginal()
print "Als Dictionary (ungeordnet):", m.__dict__
print "Als Liste (ungeordnet):", m.__dict__.values()
print


class MeineKlasseAlsListe(list):
    def __init__(self, *args):
        list.__init__(self, *args)
        
        self.append("aa")
        self.append("bb")
        self.append("cc")

m = MeineKlasseAlsListe()
print "Als Liste (geordnet):", m
print


class MeineKlasseAlsDictionary(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        
        self["a"] = "aa"
        self["b"] = "bb"
        self["c"] = "cc"

m = MeineKlasseAlsDictionary()
print "Als Dictionary (ungeordnet):", m
print
Zum Rest deiner Frage kann ich nicht viel sagen. Das ist von deinem Programm abhängig und davon was für Daten du verwalten möchtest. Vorsicht: ``__dict__`` gibt dir alles zurück was von dir an ``self`` gebunden wurde. Nicht nur deine Datenobjekte. ABER, wahrscheinlich gibt es eine viel bessere Lösung für dich, wenn du uns nicht so ein abstraktes Beispiel liefern würdest. Was willst du eigentlich machen?

mfg
Gerold
:-)

Verfasst: Donnerstag 10. Mai 2007, 11:05
von jo_hb
Aha, also __dict__ sieht doch schon nicht schlecht aus!
Die ';' waren übrigens ein Tipfehler, weil ich hier grad immer mit ;-separierten .txt-files rummache... :)

Also was ich machen will: Ergebnisse etc. von Pferderennen verwalten. Mein erster Versuch ohne Klassen hat sich nach und nach in grauenhaften Spaghetticode verwandelt, mein neuer Versuch sieht bisher so aus:

Code: Alles auswählen

# -*- coding: cp1252 -*-

import os
import time
import re

class back_lay:
    def __init__(self, back, lay):
        self.back       = back
        self.lay        = lay

class course:
    Courses	= { 'arl':['Arlington','AP'],
                    'belmont':['Belmont Park','BEL'],
                    'delaw':['Delaware Park','DEL'],
                    'fingl':['Finger Lakes','FL'],
                    'golden':['Golden Gate Fields','GG'],
                    'greatlk':['Great Lakes Downs','GLD'],
                     'hollyp':['Hollywood Park','HOL'],
                    'indiana':['Indiana Downs','IND']}
                    
    def __init__(self, inputstring):
        self.realname   = ''
        self.BFname     = ''
        self.DRFname    = ''

class odds:
    def __init__(self):
        self.timetorace = 0
        self.rank       = 0
        self.odds       = [back_lay(0,0), back_lay(0,0), back_lay(0,0)]

class runner:
    def makestring(self):
        s = ''
        d = self.makedict().values()
        for i in d:
            s = s + str(i)
            s = s + ';'
        return s
            
    def makedict(self):
        d = {}
        d['index']        = self.index
        d['raceID']       = self.raceID
        d['course']       = self.course
        d['country']     = self.country
# etc. pp.
        return d
    
    def find(self, inputstring):
        tmp = self.makedict()
        i = inputstring.split('=')
        if tmp.has_key(i[0]) and str(tmp[i[0]]) == i[1]:
            return True
        else:
            return False
        
    def __init__(self):
        self.index        = 0
        self.raceID       = ''
        self.course       = course('')
        self.country      = ''
        self.time         = ''
        self.racenr       = 0
        self.distance     = []
        self.type         = ''
        self.runners      = 0
        self.nonrunners   = 0
        self.horsenr      = 0
        self.horsename    = ''
        self.horseID      = 0
        self.odds         = odds()
        self.result       = 0

class races:
     
    def __init__(self, DB_filename):
        self.DB_filename = DB_filename
        
        self.runner = []

        DB_file = open(DB_filename)
        for DB_line in DB_file:
            linelist = DB_line.split(';')
            horse = runner()
            
            horse.raceID = linelist[0]
            horse.course.BFname = linelist[1]
            horse.country = linelist[2]
            horse.time = linelist[3]
            horse.racenr = linelist[5]
            horse.horsename   = linelist[16]
            self.runner.append(horse)
        DB_file.close()


#    def Write_DB(self, DB_filename):
#        DB_file = open(DB_filename, 'w')
#        header = self.runner[0].makedict().keys()
#        DB_file.write
#        for i in runner:
#            
#            DB_file.write


    def Filter_Races(self, filterstring):
        result = []
        for i in self.runner:
            if i.find(filterstring):
                result.append(i)
        return result

    def race_list(self):
        result = []
        for i in self.runner:
            result.append(i.raceID)
        result = set(result)
        return result
   
        
######################################################### MAIN

Path = 'C:/'

DB_filename = 'DataBase.txt'

DB = races(Path + DB_filename)

# zum Beispiel:
a = DB.Filter_Races('country=us')
for i in a:
    print i.raceID

Das DB-file ist halt wie gesagt ein ;-separiertes txt-file, sollte es auch bleiben weil ich es dann auch mit zB excel noch benutzen kann.

Habe also innerhalb der Klasse races eine Liste races.runner, und in dieser Liste die einzelnen Pferde. Was ich jetzt brauche ist eine Möglichkeit diese Liste zu filtern, weiss nicht ob das da oben jetzt ein brauchbarer Ansatz dafür wäre?

Was mich daran noch gestört hat war dass ich jetzt dachte ich müsste in jede (unter-) klasse noch die methoden make_dict und find schreiben, aber mit dem __dict_ hat sich ja jedenfalls das erste erledigt.

Hab ich denn da ansonsten irgendwie groben Unfug programmiert bisher oder irgendwas viel zu umständlich gemacht? :)

Danke!
Jo

PS bei der Gelegenheit kann ich mal sagen dass ich begeistert bin: Hab bisher im Netz selten so ein kompetentes und freundliches Forum gesehen! :)

Verfasst: Donnerstag 10. Mai 2007, 12:08
von BlackJack
Der Quelltext funktioniert so nicht wirklich. Dictionaries sind z.B. ungeordnet, dass heisst `runner.makestring()` gibt eine Zeichenkette zurück, in der die Daten mehr oder weniger zufällig angeordnet sind. Der Umweg über ein Dictionary ist aber auch nicht wirklich nötig:

Code: Alles auswählen

class runner:
    def __str__(self):
        return ';'.join(map(str,
                            (getattr(self, name) for name
                             in ('index', 'raceID', 'course', 'country'))))
Für CSV-Dateien gibt's in der Standardbibliothek übrigens ein Modul: `csv`. Insbesondere wenn man Daten mit einer Tabellenkalkulation austauschen möchte, ist das vielleicht besser als selbst geschriebener Code.

Es sieht so ein bisschen danach aus, dass hier eine relationale Datenbank eine bessere Lösung ist.