Fragen zu Klassen

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.
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Hi,
ich habe mich nun mit Klassen beschäftigt und habe einige Fragen :D


1. Was bringt das hier: "class Klasse1(object):" Was heißt das "object"?
2. Wann kann man das "object" weggelassen?
3. Bei Attributen kann man da das "self." weglassen?
4. Was bringt das self generell?
5. Frage zu folgendem Code:

Code: Alles auswählen

class Klasse1(object):
      wechselkurs=0.5
  
      def __init__(self):
             ...
Was bringt es, wenn man eine Variable vor dem Initalisieren definiert?!

Danke schonmal! :D
BlackJack

1. `object` ist hier die Basisklasse. Damit ist `Klasse1` automatisch eine "new style"-Klasse. Ohne würden zum Beispiel "properties" nicht funktionieren. In der Regel sollte man "new style" Klassen benutzen.

2. Das `object` kann man immer weglassen, wenn man eine "old style" Klasse haben möchte. "Früher" wollte man das bei Ausnahmen, weil das keine "new style" Klassen sein durften. Hat sich mittlerweile geändert.

3. Nein das `self` kann man nicht weglassen. Wie sollte man sonst Attribute von lokalen Namen unterscheiden!?

4. An `self` ist das Objekt gebunden auf dem die Methode aufgerufen wurde.

5. `wechselkurs` ist ein Klassenattribut, d.h. das teilen sich alle Klassen.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Markus12 hat geschrieben:Hi,
ich habe mich nun mit Klassen beschäftigt und habe einige Fragen :D
Sehr schön, auf gehts!
1. Was bringt das hier: "class Klasse1(object):" Was heißt das "object"?
Schwer zu erklären. Jedes Objekt erbt im enddefekt von dem Objekt

Code: Alles auswählen

object
.
Wie das genau hinter den Kullissen abläft sollte vielleicht eine vertrautere Person beschreiben.
2. Wann kann man das "object" weggelassen?
Ja. Die Klassen, die mit von 'object' erben, werden [wiki]New-Style Klassen[/wiki]genannt.
3. Bei Attributen kann man da das "self." weglassen?
Wenn du innerhalb einer Klasse darauf zugreifst:

Code: Alles auswählen

class MyClass(object):
    def __init__(self):
        self.text = "Hallo"

    def print(self):
        return self.text
Nein. Denn 'self' ist eine Referenz auf die aktuelle Klasseninstanz.
Bedeutet, dass 'self.text' synonym zu 'MyClass.text' ist.
Wo du nun auch ungefair siehst, wofür 'self' steht.
4. Was bringt das self generell?
Siehe oben

Das sind so die Dinge, die ich sagen kann.

Ich denke, das andere, wie birkenfeld, Leonidas, gerold oder BlackJack oder wie unsere Meißter hier alle heißen sicherlich mehr zu dem Thema sagen können.

MfG EnTeQuAk

€dit: mist, zu langsam...
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Erstmal Danke :D

Zu 3.:

Meinst du das Unterscheiden von lokalen Namen im Programmlauf selber? Ja, das wäre dann klar!


Zu 5.:

Heißt das, dass wenn ich jetzt eine Unterklasse "Klasse2" definieren würde und als Oberklasse "Klasse1" angeben würde (also Klasse2 erbt alle Attribut und Methoden von Klasse1 oder?), dass ich dann in Klasse2 auf das Klassenattribut "wechselkurs" zugreifen könnte, womöglich auch verändern?


Dann noch zu Properties -.-

Das habe ich nicht verstanden, was es mit Properties auf sich hat. Ich weiß, dass es hier um die Lese- und Schreibemethode geht. Aber generell kann man die Properties doch weglassen oder?

Ich hab hier in meinem Buch nachgelesen, dass, wenn man das zweite Argument weglaässt, dass man dann das Attribut einlesen, aber nicht verändern kann!

Und da man stark private Attribute ja trotzdem ändern kann, indem man z.B. schreibt: Klasse1()._Klasse1__attribut=...

dann kann man das ja ändern! Und so mit den Properties geht das nicht mehr, wenn das zweite Argument fehlt.

Liege ich damit richtig? :)


Danke!
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Vielen Danke auch an dich, EnTeQuAk! :D
Das, was self bedeutet, war mir eig. klar. Aber zur Sicherheit und Überprüfung habe ich einfach nochmal nachgefragt :)

Aber zu deinem synonym:

müsste das nicht 'MyClass().text heißen? Denn das Atrribut self.text gibts doch erst nach der Initialisierung oder? Wenn ich das richtig verstanden habe^^

Danke an euch beide :D
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Aber zu deinem synonym:

müsste das nicht 'MyClass().text heißen? Denn das Atrribut self.text gibts doch erst nach der Initialisierung oder? Wenn ich das richtig verstanden habe^^
Was durchaus richtig ist. Da war mein Kopf wohl schon zwei Klammern weiter als meine Finger.

Heißt das, dass wenn ich jetzt eine Unterklasse "Klasse2" definieren würde und als Oberklasse "Klasse1" angeben würde (also Klasse2 erbt alle Attribut und Methoden von Klasse1 oder?), dass ich dann in Klasse2 auf das Klassenattribut "wechselkurs" zugreifen könnte, womöglich auch verändern?
gut erkannt.

Es gibt aber einen Unterschied, zu normalen Attributen und Klassenattributen.

Wir gehen mal davon aus, das wir folgende Basisklasse haben:

Code: Alles auswählen

>>> class Base(object):
...     test = "test"
...     def __init__(self):
...         self.hammer = "hammer"
Wenn wir nun folgende 'sub' Klasse definieren:

Code: Alles auswählen

class Sub(Base):
    pass
Also eine, die absolut gar nichts macht, sind alle Attribute, sowohl das Klassenattribut 'test' als auch das Attribut 'hammer' weiterhin verfügbar.

Weiter gehts:

Code: Alles auswählen

class Sub(Base):
    def __init__(self):
        self.my_new_var = "lalala"
Versuche mal bei dieser Klasse, auf das Attribut 'hammer' zuzugreifen. Es wird nicht gehen, da die __init__ Methode überschrieben wurde und das Attribut 'hammer' *nicht* initialisiert wurde.

Was allerdings weiterhin geht, ist der Zugriff auf 'test'.

Klassenattribute können afaik nur geändert werden, nicht aber (wie oben zu sehen) gelöscht/entfernt/überschrieben werden.

MfG EnTeQuAk
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Es hat sich auf jeden Fall gelohnt hier im Forum nachzuhacken :D
Danke vielmals. Jetzt ist einiges klarer!

Nochmal zu den Klassenattributen:

Ist das evtl. also ein Problem, wenn man im Programmlauf eine Varible definiert vor der Instanzierung der Klasse, die genauso heißt wie ein Klassenattribut?

Also, im Klartext:
Wenn ich im Prgrammlauf eine variable 'test' definieren würde und dann die Klasse 'Base' aufrufe, dass dann die lokale Variable überschrieben wird?
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Nein, denn deine Variable 'test' ist auch unter dem Namen 'test' zu erreichen.

(Klassen-)Attribute sind unter 'Klasse.attribut' zu erreichen.

Und

Code: Alles auswählen

print test
ist ganz was anderes, als

Code: Alles auswählen

print Base().test
.


MfG EnTeQuAk
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Ja, ich hab das gerade in der Pyhon-Shell ausprobiert und woltle auch gerade mich verbessern ;)

Das Klassenattirbut muss nämlich mit dem Klassennahmen davor aufgerufen werden. Aber diesmal hast du wieder einen Fehler drin, denn diesmal wird die Klasse nicht initialisiert!

Hier also:

Code: Alles auswählen

Base.test
;)

Aber das war bestimmt nur ein Denkfehler. Ich bin froh, dass andere, die sich besser mit Python auskennen, anderen helfen! :D


So jetzt ists klar :D
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Und nochmal eine grundlegende Frage! :)

Ich habe für ein Programm zwei Klassen. Die erste vererbt alles der zweiten.
Die erste hat eine __init__ - Methode, die zweite Klasse aber nicht, weil sie nur aus statischen Methoden besteht.

Ich habe dazu noch ein Klassenattribut in der ersten Klasse definiert, dass aber in der zweiten Klasse nicht abgerufen werden kann.

Da meine Erklärung etwas kompliziert war, hier der Aufbau:

Code: Alles auswählen

class Klasse1(object):
        attribut='...'

        def __init__(self):
                pass

class Klasse2(Klasse1):
        def methode1():
                return attribut

        def methode2():
                attribut='hallo'

        methode1=staticmethod(methode1)
        methode2=staticmethod(methode2)


Hängt das vielleicht daran, dass man ein Klassenattribut nicht ändern kann oder dass das mit den statischen Methoden zusammenhängt?

Danke schonmal :D
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Du musst es ueber self.attribut ansprechen. Also z.b.

Code: Alles auswählen

        return self.attribut
BlackJack

Was natürlich nicht mit den statischen Methoden geht, die kennen ja kein `self`.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Hehe, ist auch wieder wahr. :lol:

Was mich anfangs irritiert hat, ist, dass Python einen Unterschied zwischen statischen Methoden und Klassenmethoden macht, und manchmal passiert es mir immer noch, dass ich da nicht dran denke.

Hier waere also eine Klassenmethode angebracht.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Markus12 hat geschrieben:Die erste hat eine __init__ - Methode, die zweite Klasse aber nicht, weil sie nur aus statischen Methoden besteht.
Dann versuchst du, Java in Python zu schreiben ;)

Eine Klasse, die nur aus statischen Methoden besteht, macht keinen/wenig Sinn, in Java ist es aber notwendig, da es nur Klassen gibt.

Die "pythonische Lösung" wäre, die Funktionen in ein eigenes Modul zu packen, also z. B.

Vorher:

Code: Alles auswählen

# Datei1.py
class Foo(object):
   ... #normale Klasse

class Bar(object):
  @staticmethod
  def baz():
    print "Hallo, Welt"
Jetzt löscht du Bar aus Datei1 und legst eine Datei bar.py an, mit dem Inhalt:

Code: Alles auswählen

def baz():
    print "Hallo, Welt"
Dann legst du im selben Verzeichnis noch eine leere Datei namens "__init__.py" an, und dann kannst du mit baz arbeiten:

Code: Alles auswählen

# Möglichkeit 1
import bar
bar.baz() # Hallo Welt
# Möglichkeit 2
from bar import baz
baz() # Hallo, Welt
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Danke, aber so schwer wollte ich das nicht machen ;)
Ich will EIN Script, das übersichtlich sein soll, indem Zusatzfunktionen in einer extra Klasse deponiert sind ;)

Ich könnte es auch in eine Klasse schreiben, aber dadurch wird es eben unübersichtlich und zu einfach und langweilig -.-

Weiß jemand noch eine andere Lösung, ohne irgendwas zu importieren, eine andere Datei anlegen zu müssen, oder es unnötig kompliziert zu machen? ^^
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Also entweder es sind so viele Funktionen, dass sich dafuer eigene Module lohnen, oder man laesst die Funktionen als Top-Level-Funktionen im Script.

Meine Meinung.
BlackJack

@Markus12: IMHO sind Klassen die nur aus statischen Methoden bestehen ein Missbrauch von Klassen. Die vorgesehene Einheit zum organisieren von Funktion ist nunmal das Modul. Statische Methoden, oder noch besser Klassenmethoden, sollten sich auf alternative "Konstruktoren" und Funktionen beschränken, die wirklich *ganz* eng mit einer Klasse verbunden sind.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

BlackJack hat geschrieben:IMHO sind Klassen die nur aus statischen Methoden bestehen ein Missbrauch von Klassen.
Hallo BlackJack!

Ich habe den Thread nicht gelesen. Ich beziehe mich hier nur auf oben gezeigt Aussage.

Klassen eignen sich hervorragend auch zum Gruppieren von **zusammengehörenden** Funktionen. Ich mache das zwar recht selten, aber nur weil du das ablehnst fällt es mir trotzdem nicht im Traum ein, diese Art der Quellcodeorganisation von vorneherein abzulehnen.

Was ich damit sagen will? Ich glaube, dass du da ein wenig zu engstirnig denkst.
Namespaces are one honking great idea -- let's do more of those!
Wie kann man noch einfacher Namespaces erstellen, als mit Klassen? Nein, Module sind es sicher nicht. Ein Programm in *einem* Modul ist meistens einfacher als ein Programm in vielen Modulen.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Ja, genau so wollte ich das auch machen. Ein Programm aus mehreren Klassen.
BlackJack

@gerold: Das Klassen nicht als Namensraum für Funktionen gedacht sind, sieht man ja schon daran, dass man sie besonders behandeln muss (`staticmethod()`) damit das überhaupt funktioniert.

Das kann man natürlich machen, genauso wie man eine Datei pro Klasse benutzen kann, oder ähnliches. Ich finde es schlechten Stil. Wenn es soviele Funktionen in einem Modul gibt, dass man die sinnvoll gruppieren kann bzw. muss um den Überblick zu behalten, ist es IMHO Zeit das Ganze zu refaktorisieren.
Antworten