Problem mit Klassen (byteofpython)

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
DrChAoS
User
Beiträge: 14
Registriert: Montag 10. März 2008, 16:29

Montag 10. März 2008, 20:16

Hallo alle zusammen.
Ich habe vor ein paar Tagen mit Python angefangen und habe mir als Einstieg vorgenommen mit dem Ebook Byteofpython anzufangen. Da bin ich jetzt bei den Klassen angelangt, aber ich komme gerade leider nicht weiter.

Das Beispiel mit der Klasse Person habe ich mal auf die Klasse Auto angepasst. Im Prinzip ist es genau das selbe, aber es funktioniert nicht.

Hier mal meine Klasse Auto:

Code: Alles auswählen

#!/usr/bin/python
#-*- coding: utf-8 -*-

class auto:
    anzahl = 0

    def __init__(self, name):
        self.name = name
        auto.anzahl += 1
    def __del__(self):
        print 'Das Auto %s ist schrott' % self.name
        auto.anzahl -= 1
        print 'Es gibt noch %s Auto(s)' % auto.anzahl
    def hupen(self):
        print '%s hupt' % self.name
    def zahl(self):
        print "Es gibt noch %s Auto(s)" % auto.anzahl

blau = auto('blau')
rot = auto('rot')

rot.hupen()
blau.hupen()

rot.zahl()
blau.zahl()
Und hier die von mir abgewandelte Klasse Person aus dem Ebook (welche funktioniert.):

Code: Alles auswählen

#!/usr/bin/python


class Person:
    bevoelkerung = 0

    def __init__(self, name):
        self.name = name
        Person.bevoelkerung += 1
    def __del__(self):
        print '%s verabschiedet sich.' % self.name
        Person.bevoelkerung -= 1
        print 'Es gibt noch %d Leute.' % Person.bevoelkerung
    def sagHallo(self):
        print 'Hallo, mein Name ist %s.' % self.name
    def wieViele(self):
        print 'Es gibt hier %d Leute.' % Person.bevoelkerung


swaroop = Person('Swaroop')
swaroop.sagHallo()
swaroop.wieViele()
kalam = Person('Abdul Kalam')
kalam.sagHallo()
kalam.wieViele()
swaroop.sagHallo()
swaroop.wieViele()
Die Ausgabe meiner Klasse Auto sieht immer so aus:

Code: Alles auswählen

rot hupt
blau hupt
Es gibt noch 2 Auto(s)
Es gibt noch 2 Auto(s)
Das Auto blau ist schrott
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'anzahl'" in <bound method auto.__del__ of <__main__.auto instance at 0xb7d0d8cc>> ignored
Das Auto rot ist schrott
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'anzahl'" in <bound method auto.__del__ of <__main__.auto instance at 0xb7d0d9ac>> ignored
Hier noch meine Python Version:

Code: Alles auswählen

Python 2.5.1 (r251:54863, Oct  5 2007, 13:36:32) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Kann mir jemand sagen was ich falsch mache?
MfG
Dr.ChAoS

PS: Ich habe mich als erstes mit dem namen "Dr.ChAoS" registriert, aber die bestätigungs Mail kam nicht an. Also ihr könnt den alten löschen.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 10. März 2008, 20:28

DrChAoS hat geschrieben:Kann mir jemand sagen was ich falsch mache?
Du benuzt ``__del__``. Vergiss am besten dass es ``__del__`` gibt, denn das braucht man nahezu nie. Ich glaube nicht, dass ich in den Jahren Python mal ``__del__`` gebraucht hätte.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
DrChAoS
User
Beiträge: 14
Registriert: Montag 10. März 2008, 16:29

Montag 10. März 2008, 20:39

Ok danke. Dann werde ich das wohl so akzeptieren. :D
MfG
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 10. März 2008, 20:43

Wobei es schon lustig ist, dass das zweite Beispiel wirklich funktioniert! Ich sehe da irgend wie keinen signifikanten Unterschied!

Also nimmt man statt auto.anzahl immer self.anzahl klappts übrigens!

Aber mich würde das jetzt auch mal interessieren :-)
BlackJack

Montag 10. März 2008, 21:28

Mit `self.anzahl` funktioniert es nicht. Das hat eine andere Semantik als das Klassenattribut.

Was hier passiert ist, dass am Ende des Programms alle Objekte abgeräumt werden. Zugriffe auf abgeräumte Module und anscheinend auch Klassen werden durch `None` ersetzt. Das Modul wird vor den `auto`-Exemplaren abgeräumt. Wenn deren `__del__()`-Methoden aufgerufen werden, dann können die nicht mehr auf die Klasse zugreifen, weil das Modul schon weg ist.

Dass das im anderen Programm nicht passiert ist reiner Zufall.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dienstag 11. März 2008, 10:35

BlackJack hat geschrieben:Mit `self.anzahl` funktioniert es nicht. Das hat eine andere Semantik als das Klassenattribut.
Inwiefern? Vor allem: Ist es dann auch "Zufall", dass es bei mir funzt?
BlackJack

Dienstag 11. März 2008, 11:20

Wenn Du immer `self.anzahl` schreibst, wird nicht das Attribut der Klasse hochgezählt, sondern jedes Auto nimmt die 0 von der Klasse, addiert 1 und speichert das Ergebnis als Attribut des Objekts. Wenn Dein Code da wirklich bis zwei zählen kann, stimmt etwas mit Deinem Python nicht.
Antworten