Listen als Attribut eine Klasse

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
alfonsospringer
User
Beiträge: 34
Registriert: Sonntag 24. August 2008, 21:50

Hi zusammen!

Wenn ich eine Klasse erstelle kann ich ja im Konstruktor ihre Attribute festlegen. Nun möchte ich als eines dieser Attribute eine Liste haben. Der Inhalt der Liste ist mir zu diesem Zeitpunkt jedoch noch nicht bekannt. Wie vermittle ich dann Python, was für einen Inhalt die Liste später umfassen wird? Oder denke ich da zu statisch (längere Zeit c++ programmiert) ?

Code: Alles auswählen

class test:
    def __init__(self):
        liste[] = ??? #Die Liste soll später zb Ints beinhalten. Wie definiere ich denn nun die Liste? 
    def __del__(self):
        pass

Versteht ihr, was ich meine? Vielen dank schonmal


/edit: habs.

Code: Alles auswählen

liste = []
definiert eine leere Liste.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

eine leere Liste, die du später befüllst, legst du an mit

Code: Alles auswählen

mylist = list()
# oder
mylist2 = []
EDIT: Sorry, hab dein Edit zu spät gesehen ^^
alfonsospringer
User
Beiträge: 34
Registriert: Sonntag 24. August 2008, 21:50

NP, vielen Dank
BlackJack

@alfonsospringer: Vergiss bitte das es `__del__()` gibt. Das ist nicht wirklich zu gebrauchen weil nicht garantiert wird, wann die Methode aufgerufen wird, oder ob das *überhaupt* jemals passiert. Das reine Vorhandensein der Methode verhindert unter Umständen sogar, dass Objekte aus dem Speicher entfernt werden können.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Kleines Detail am Rande: Dein Attribut `liste' - auch wenn die Syntax nicht stimmt - ist ein Klassenattribut.
Falls du ein Instanzattribut brauchst musst du `self.liste = []' nehmen. Das wird allerdings nicht so recht deutlich was du brauchst ;)

Zu `__del__': Das kannst du getrost weg lassen, denn der GC kümmert sich um die Entsorgung, ausserdem verleitet es dazu Logik reinzupacken und das sollte man in Python gar nicht tun ;)
alfonsospringer
User
Beiträge: 34
Registriert: Sonntag 24. August 2008, 21:50

Magst du mir noch bitte den Unterschied zwischen Instanzattribut und Klassenattribut nennen?
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Ein Klassenattribut ist ein Attribut des Klassenobjekts, ein Instanzattribut ist ein Attribut der Instanz.

Code: Alles auswählen

In [120]: class Foo(object):
   .....:     bar = []
   .....:     
   .....:     def __init__(self):
   .....:         self.mybar = []
   .....:     
   .....:     def append(self, obj):
   .....:         self.bar.append(obj)
   .....:         self.mybar.append(obj)
   .....: 

In [121]: foo1 = Foo()

In [122]: foo2 = Foo()

In [123]: foo1.append("A")

In [124]: foo2.append("B")

In [125]: print foo1.bar
['A', 'B']

In [126]: print Foo.bar
['A', 'B']

In [127]: print foo1.mybar
['A']
bar ist hierbei das Klassenattribut und mybar das Instanzattribut.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

BlackJack hat geschrieben:@alfonsospringer: Vergiss bitte das es `__del__()` gibt. Das ist nicht wirklich zu gebrauchen weil nicht garantiert wird, wann die Methode aufgerufen wird, oder ob das *überhaupt* jemals passiert. Das reine Vorhandensein der Methode verhindert unter Umständen sogar, dass Objekte aus dem Speicher entfernt werden können.

oha ... danke. Ich dachte das sei nötig, und hab daher z.B. in eine Klasse die ich für Datenbankverbindungen geschrieben hab (baut z.B. Verbindung zu Oracle auf, und managed Abfragen, Updates, .... ) extra ein __del__ eingebaut, damit auf jedenfall die Verbindung zur Datenbank geschlossen wird:

Code: Alles auswählen

def __del__(self):
        self.db.close()
.. ist demnach gar nicht gut und nicht zu gebrauchen?
lunar

__del__ sollte nie benutzt werden, um Ressourcen zu bereinigen. Dafür gibt man der Klasse eine explizite close()-Methode (oder disconnect(), oder was auch immer passend ist). Zudem bietet sich an, in einer solchen Klasse das Kontextmanager-Protokoll zu implementieren, damit die Klasse in einer "with"-Statement verwendet werden kann.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

zu was ist __del__ dann überhaupt gut?
alfonsospringer
User
Beiträge: 34
Registriert: Sonntag 24. August 2008, 21:50

Juhu, ich kann auch mal eine Frage beantworten!

bei __del__(self): handelt es sich um den Destruktor einer Klasse. Diese funktion wird ausgeführt, wenn die Instanz einer Klasse stirbt. Ein kleines Beispiel:

Code: Alles auswählen

class testklasse():
   def __init__(self):
        print "Ich wurde grade erschaffen"
   def __del__(self):
        print "Ich bin grade gestorben"

a = testklasse()
del a
Mit a = test() erstellst du eine neue Instanz der Klasse testklasse. Dadurch wird der Konstruktor ( __init__(self): ) ausgeführt. Der erste Text wird folglich ausgegeben. Durch del a wird die Instanz wieder gelöscht, was bewirkt, dass der Destruktor ( __del__(self): ) ausgeführt wird. Der zweite Text wird folglich ausgegeben.

Hoffe damit ist deine Frage beantwortet
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

alfonsospringer hat geschrieben: Hoffe damit ist deine Frage beantwortet
^^ nee. Genau DESWEGEN hab ich __del__ ja verwendet und dort Code reingepackt, der ausgeführt werden soll, wenn die Klasse "stribt". Wird somit ja auch ausgeführt, wenn aus irgendeinem Grund mein Script abstürzt oder was weiß ich. ... erzählte mir zumindest ein Java-Entwickler
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

alfonsospringer hat geschrieben:Juhu, ich kann auch mal eine Frage beantworten!

bei __del__(self): handelt es sich um den Destruktor einer Klasse. Diese funktion wird ausgeführt, wenn die Instanz einer Klasse stirbt. Ein kleines Beispiel
Schoen waers, ob der ausgefuehrt wird wenns garbage-collected wird ist afaik nicht sicher.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
lunar

meneliel hat geschrieben:
alfonsospringer hat geschrieben: Hoffe damit ist deine Frage beantwortet
^^ nee. Genau DESWEGEN hab ich __del__ ja verwendet und dort Code reingepackt, der ausgeführt werden soll, wenn die Klasse "stribt". Wird somit ja auch ausgeführt, wenn aus irgendeinem Grund mein Script abstürzt oder was weiß ich. ... erzählte mir zumindest ein Java-Entwickler
Und wie kommst du darauf, dass eine für Java gültige Aussage automatisch auch für Python Gültigkeit hätte? Auch in Java ist es schlecht, zum Bereinigen von Ressourcen finalize() zu nutzen. Im Gegenteil, Java-Objekte, die Ressourcen repräsentieren, haben alle eine dispose() oder close() Methode.

Auch in Java sollte eine Klasse niemals Logik im Destruktor ausführen. Der Java-GC ist da sogar noch schlechter geeignet als der Python-GC. Ersterer arbeitet überhaupt nicht deterministisch, es kann durchaus vorkommen, dass der gc während der Laufzeit eines Programms niemals abläuft. CPythons GC dagegen ist noch relativ deterministisch, weil er Objekte sofort abräumt, wenn der Refcount 0 erreicht. Wobei das natürlich ein Implementierungsdetail von CPython darstellt und weder IronPython noch iin Jython der Fall ist.
Ich bin mir nicht mal sicher, dass die JVM den Aufruf von finalize() garantiert.

@name
Die Doku sagt nur: "It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits. " Ich interpretiere das so, dass der Aufruf von __del__ garantiert wird, wenn ein Objekt während der Laufzeit gelöscht wird. Allerdings ist der Aufruf von __del__ trotzdem weiter nicht deterministisch, so dass sowohl Zeitpunkt als auch Umstände des Aufrufs nicht vorhersehbar sind.
Antworten