Frage zu Klassen-Attributen ?

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
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo,

schon wieder ne dumme Frage...

Beispiel:

Code: Alles auswählen

class Pizza(object):
    def __init__(self, size):
        self.size = size
    def get_size(self):
        return self.size
Kann ich auf size nur per get_size() zugreifen ?

Code: Alles auswählen

a = Pizza(10)
b = get_size() 
oder geht auch

Code: Alles auswählen

b = a.size
Pycharm möchte dafür gerne statische Klassen-Attribute haben.

Grüße
mephisto
Zuletzt geändert von mephisto-online am Montag 27. Januar 2014, 01:17, insgesamt 1-mal geändert.
BlackJack

@mephisto-online: Da sollte sich die IDE oder spätestens der Compiler eher über einen Einrückungsfehler beschweren, das ist so nämlich nicht lauffähig. Hör doch mal auf die Beispiele hier kaputt anzuliefern. ;-)

Und dann hättest Du das doch ganz einfach mal ausprobieren können:

Code: Alles auswählen

In [3]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:class Pizza(object):
:    def __init__(self, size):
:        self.size = size
:    def get_size(self):
:        return self.size
:--

In [4]: a = Pizza(10)

In [5]: a.get_size()
Out[5]: 10

In [6]: a.size
Out[6]: 10
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Mein Gott ! Ein Leerzeichen zu viel ! Ich hatte es nicht reinkopiert, sondern geschrieben. Du meintest glaube ich auch Interpreter nicht Compiler ...

Natürlich habe ich es ausprobiert. In einem einfachen Test-Script geht es natürlich, in meinem Programm aber auf die gleiche Weise in einer Methode halt nicht! Da will PyCharm statische Klassen-Attribute. Sonst hätte ich nicht gefragt. Ja, war an sich ne blöde Frage. Hätte ja aber sein können, dass es nicht in jedem Fall so geht.

Was jetzt der Unterschied zwischen w.o. erzeugten Attributen und statischen Attributen ist , ist mir halt nicht klar. Wie man sie definiert, schon, aber nicht, wann man es besser auf die eine oder andere Art macht.

Keine Sorge, ich werde hier jetzt aber nichts mehr fragen. Scheint hier ja eher was für Python-Cracks mir richtigen Problemen zu sein.

Ich bin hier übrigens auch nicht zum ersten mal fertig gemacht worden, wegen jeder Kleinigkeit, wegen jedem Sch.... Das brauche ich nicht ! Danke ! Hier kommt man sich ja vor wie beim Kommiss ! Bin freundlichere Foren gewohnt.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

mephisto-online hat geschrieben:Was jetzt der Unterschied zwischen w.o. erzeugten Attributen und statischen Attributen ist , ist mir halt nicht klar. Wie man sie definiert, schon, aber nicht, wann man es besser auf die eine oder andere Art macht.
Also AFAIK sind statische Attribute Klassenattribute (was nun aber statische Klassenattribute sein sollen weiß ich nicht)

Es gibt in Python Klassenattribute, also Attribute die über alle Instanzen der Klasse gleich sind und Instanzattribute, also Attribute die
für jede Instanz der Klasse anders sein können.

Beispiel:

Code: Alles auswählen

class A:
    a = 1
    def __init__(self):
        self.b = 2
a wäre hier ein Klassenattribut, b ein Instanzattribut.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

p90 hat geschrieben:Also AFAIK sind statische Attribute Klassenattribute (was nun aber statische Klassenattribute sein sollen weiß ich nicht)
Das habe ich hier http://stackoverflow.com/questions/6864 ... -in-python wohl falsch benannt gefunden. Ich meinte natürlich, korrekt benannt, Klassen-Attribute. Habe jetzt mit Instanz-Attributen realisiert, was ich vor hatte. Wie sich Klassen-Attribute verhalten, werde ich morgen mal ausprobieren und googeln, wo denn genau der Unterschied ist (Wenn ich eine Klasse instanziere, sind die Instanz-Attribute ja auch erst mal immer gleich. Klassen-Attribute wird man aber doch wahrscheinlich auch ändern können, ansonsten wären sie ja Konstanten). Werde das nochmal "nachstudieren". Bin übrigens trotz der Anfeindungen hier immer noch von der Python Sprache total begeistert. Es ist eine wirklich schöne Sprache ! Brauch nur noch ein wenig, bis ich alles richtig kapiert habe. Auch die Terminologie.

Danke
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Also ich kann hier keine Anfeindung oder sonstiges unfreundliches Verhalten erkennen. Der Hinweis, dass man Code ausprobieren kann, bevor man fragt "was passiert, wenn …?" ist hier doch legitim. Es kann bei deinem Code jedenfalls nicht befürchtet werden, dass Dateien gelöscht werden oder ähnliche schlimme Sachen passieren. Bei CPython, der Standard-Implementierung von Python, kann man übrigens nicht knallhart zwischen Compiler und Interpreter trennen. Es wird zuerst der Python-Code in Bytecode übersetzt (also kompiliert) und dieser Bytecode dann interpretiert. Der Bytecode steckt in den Dateien, dessen Namen auf .pyc enden. Und frag ruhig weiter, dazu ist das Forum ja da ;) nicht abgeschreckt fühlen, nur weil eine knappe Antwort unhöflich erscheinen mag (aber auf keinen Fall so gemeint ist, bin selber jemand, der sich selber eigentlich immer sehr kurz fasst).
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Ja, nehme Kritik zu schnell persönlich. Aber irgendeine Macke hat ja doch jeder. Der Eine ist zu schulmeisterlich, der andere zu militant und wieder der Nächste halt einfach zu empfindlich.

Komme aber jetzt gut zurecht. Das mit den Zwei verschiedenen Arten von Attributen habe ich hier http://cgvr.cs.uni-bremen.de/teaching/i ... _6up_4.pdf hinreichend erklärt gefunden. Und auch ansonsten komme ich langsam richtig gut voran. Nur am Anfang, da ging irgendwie garnichts. Deshalb war ich ein bisschen genervt.

Und danke für die Erklärung Compiler/Interpreter.
BlackJack

@mephisto-online: Das war von mir nicht als Anfeindung gedacht. Ich hatte extra einen Smilie dahinter gesetzt, um klar zu machen dass das nicht böse gemeint war. :-( Ich bin oft sehr knapp und kippe einfach nur die Problempunkte kurz und hoffentlich halbwegs sachlich ab.

Zu den verlinkten Folien sollte man noch dazu sagen, dass man das Beispiel mit Vorsicht geniessen sollte. Das mit `__class__` sieht auf den ersten Blick vielleicht clever aus, aber ich vermute mal ganz stark das der Autor sich dabei keine Gedanken darüber gemacht hat was passiert wenn man `increment()` auf einer Unterklasse ausführt und welches `x`-Attribut dann vor und nach dem `increment()` auf welchem Klassenobjekt mit welchem Wert existiert. In der Praxis kommen Neuzuweisungen an Klassenattribute sowieso sehr selten vor, und wenn dann sollte man explizit den Klassennamen verwenden und nicht das `__class__`-Attribut auf einem Objekt, in der Hoffnung das wird schon die richtige Klasse sein.

Über ein Objekt kommt man an Klassenattribute auch direkt heran, also statt ``a.__class__.x`` würde man in der Praxis nur ``a.x`` schreiben.

Abschliessend: Was auch immer das ursprüngliche Problem war, wenn es sich nicht um Konstanten handelt die dann auf der Klasse definiert wurden, ist es wahrscheinlich nicht ganz koscher, denn etwas anderes als Konstanten macht nur in sehr wenigen Fällen Sinn.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:ch bin oft sehr knapp und kippe einfach nur die Problempunkte kurz und hoffentlich halbwegs sachlich ab.
Naja, klappt dann doch nicht immer so richtig :wink:
BlackJack hat geschrieben:Zu den verlinkten Folien sollte man noch dazu sagen, dass man das Beispiel mit Vorsicht geniessen sollte.

Hier meinte ich ja auch lediglich diese Aussage in dem Kasten "Zwei Arten von Attributen".
BlackJack hat geschrieben:Das mit `__class__` sieht auf den ersten Blick vielleicht clever aus, aber ich vermute mal ganz stark das der Autor sich dabei keine Gedanken darüber gemacht hat was passiert wenn man `increment()` auf einer Unterklasse ausführt und welches `x`-Attribut dann vor und nach dem `increment()` auf welchem Klassenobjekt mit welchem Wert existiert. In der Praxis kommen Neuzuweisungen an Klassenattribute sowieso sehr selten vor, und wenn dann sollte man explizit den Klassennamen verwenden und nicht das `__class__`-Attribut auf einem Objekt, in der Hoffnung das wird schon die richtige Klasse sein.
Sorry, so einem Blödsinn würde ich ja auch nicht machen. Fällt mir auch jetzt gar nichts ein, wo man das so machen müsste.
BlackJack hat geschrieben:Über ein Objekt kommt man an Klassenattribute auch direkt heran, also statt ``a.__class__.x`` würde man in der Praxis nur ``a.x`` schreiben.
`a.__class__.x`zu schreiben, würde mir auch nicht in den Sinn kommen, warum auch ?
BlackJack hat geschrieben:... denn etwas anderes als Konstanten macht nur in sehr wenigen Fällen Sinn.
z.B. Instanzenzähler.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@mephisto-online: wie schon öfter hier im Forum diskutiert, ist ein Instanzenzähler absolut nie sinnvoll.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Man sollte niemals nie sagen ! Man kann ja schließlich nicht ALLES überblicken. :wink:
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nun ok, er ist dann sinnvoll wenn du nicht wissen willst, wie viele Exemplare es momentan gibt, sondern wie viele schon erzeugt wurden.

Wie weit man das jetzt sinnvoll verwenden kann sei mal dahingestellt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

cofi hat geschrieben:Wie weit man das jetzt sinnvoll verwenden kann sei mal dahingestellt.
Das habe ich mich auch schon immer gefragt. Ich habe in den hmm, 11 Jahren die ich Python mache und wenn man vorherige Erfahrung mit Turbo Pascal & Visual basic einrechnet kein Einziger nützlicher Anwendungsfall für so einen Zähler aufgefallen aber natürlich zahllose Tutorials die genau sowas demonstrieren. Im Python-Kontext macht es mangels deterministischen Konstruktor noch deutlich weniger Sinn, man hat letztendlich eine globale Variable die immer nach oben geht und auf irgendeinen aussagelosen Wert zeigt. :K
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Also ich habe das schon mal verwendet um jedem Exemplar eine fortlaufende Nummer zu geben um die dann hinterher in der Reihenfolge sortieren zu können in der sie erzeugt wurden. Das war mit einer Metaklasse verbunden die so etwas ähnlich deklaratives wie ORMs das machen gebraucht hat. Also etwas in dieser Art:

Code: Alles auswählen

class A(Base):
    a = X('x')
    b = X('y')
    # ...
Und die Metaklasse brauchte die Attribute der Klasse `A` in der Reihenfolge in der sie erstellt wurden um daraus dann Properties für Objekte vom Typ `A` zu erstellen. Klar, man hätte auch den `ctypes`-Ansatz nehmen können und diese Klassenattribute in einer Liste angeben können, aber ich fand das bei SQLAlchemy sieht hübscher aus.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlackJack: inzwischen würde man ja beim Erzeugen der Klasse durch __prepare__ der Metaklasse statt eines dicts ein OrderedDict zurückgeben. Damit bleibt die Reihenfolge der Attribute erhalten.
Antworten