Klassenattributte umbn(__init__ aufruf...was ruft er da auf)

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.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

rolgal_reloaded hat geschrieben::!: :D

Alles klar, aber wäre es nicht doch besser, die Defaultwerte in __init__ reinzuschreiben. Entspricht das nicht mehr der Idee eines Konstruktors?

Also:

Code: Alles auswählen

class A:
    def __init__(self, var1 = [], var2 = []): #usw.
        self.var1 = var1
        self.var2 = var2

Es gibt eine Initialisierung der Klasse (i.d.R. beim Programmstart ausgeführt) und je eine Initialisierung pro Instanz. Was Du jetzt geschrieben hast, entspricht [EDIT: ebenfalls nicht (siehe BlackJacks Erklärung unten)] grandmas Vorschlag. Allein der Zweck entscheidet hier, wo man Namen initialisiert. Aber ich finde, Du hast Recht: Konstanten kann man im Namensraum der Klasse definieren. :-)

Grüße,
Michael
Zuletzt geändert von Michael Schneider am Dienstag 19. Juni 2007, 12:39, insgesamt 1-mal geändert.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Danke für die Klarstellung, wieder was wichtiges konkretisiert im Oberstübchen,

liebe Grüße

rolgal_reloaded
BlackJack

rolgal_reloaded hat geschrieben:Alles klar, aber wäre es nicht doch besser, die Defaultwerte in __init__ reinzuschreiben. Entspricht das nicht mehr der Idee eines Konstruktors?

Also:

Code: Alles auswählen

class A:
    def __init__(self, var1 = [], var2 = []): #usw.
        self.var1 = var1
        self.var2 = var2
Oder gibt es Fälle wo das wie vom Autor des Threads gezeigt wird besser ist?
Das ist nicht viel anders oder besser als Klassenattribute weil die Defaultwerte, genau wie Klassenattribute nur *einmal* ausgewertet werden, nämlich wenn das ``def __init__(...)`` ausgeführt wird:

Code: Alles auswählen

In [1]: class A(object):
   ...:     def __init__(self, var1=[], var2=[]):
   ...:         self.var1 = var1
   ...:         self.var2 = var2
   ...:

In [2]: x = A()

In [3]: y = A()

In [4]: x.var1.append(42)

In [5]: x.var1
Out[5]: [42]

In [6]: y.var1
Out[6]: [42]

In [7]: x.var1 is y.var1
Out[7]: True
Auch das ist sehr wahrscheinlich nicht das Verhalten was man im allgemeinen Fall gerne hätte.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@BlackJack

Hast es wieder geschafft mich zu verwirren bzw. mir klar zu machen, dass mir da etwas ganz und gar nicht so klar ist. :D

Dass sich die Modifizierung von Klassenattributen auf alle Instanzen auswirken kann, wie von Michael gezeigt, erscheint mir logisch.

Aber warum denn in meinem Beispiel. Und warum passiert hier was anderes:

Code: Alles auswählen

>>> class A(object):
	def __init__(self):
		self.var1 = []
		self.var2 = []

		
>>> x = A()
>>> y = A()
>>> x.var1.append(42)
>>> x.var1
[42]
>>> y.var1
[]
>>> 
LG

rolgal_reloaded
grandma
User
Beiträge: 26
Registriert: Mittwoch 30. Mai 2007, 15:04

Das wird ja noch richtig interessant hier.

Ich habe auch keine Ahnung warum sich hier in den anderen Objekten etwas ändert.

Ich hab mal den Threadtitel umbenannt...
BlackJack

Die Erklärung habe ich eigentlich schon gegeben:

Code: Alles auswählen

class A(object):
    def __init__(self, var1=[]):
        self.var1 = var1
        self.var2 = []
Der Ausdruck hinter dem '=' in der Funktionsdefinition wird ein einziges mal ausgewertet, nämlich dann wenn das ``def`` als Teil der Klassendefinition ausgeführt wird. Das Ergebnis dieses Ausdrucks wird bei jedem Aufruf der Methode an den Namen `var1` gebunden. Das ist immer die selbe Liste.

Der Körper der Funktion wird dagegen bei jedem Aufruf der Funktion abgearbeitet. Das heisst `self.var2` wird jedesmal an eine neue Liste gebunden.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

BlackJack hat geschrieben:Die Erklärung habe ich eigentlich schon gegeben:
Naja, so wie oben eben nicht, sonst hätte ich (wir) nicht nachgefragt :D

Jetzt ist klar warum das so ist.
Aber ist das eigentlich gut, dass es so ist, oder sollte das nicht anders sein??

Oder anders gesagt: weiss ich jetzt endlich, warum ein Konstruktor wie am Anfang des Threads gezeigt sinnvoll sein kann.

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Also ich finde das immer noch schräg......

Wer noch, oder wer nicht? Und vor allem wenn nicht, W A R U M ???
BlackJack

An der Stelle muss(te) man ein Entscheidung treffen: Werden Default-Werte einmal berechnet wenn die Funktion definiert wird, oder jedesmal wenn die Funktion aufgerufen wird.

Zwei Gründe für's einmalige berechnen:

a) Es muss nur einmal gemacht werden. :-)

b) Berechnen bei jedem Funktionsaufruf kann man auch *in* der Funktion machen, wenn man das braucht.

In den allermeisten Fällen sind die Default-Werte in der Praxis nach meiner Erfahrung sowieso "immutables", da braucht man nur eine Auswertung.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@BlackJack

...was meinst du jetzt mit immutables? - Beispiel?

:D

LG

rolgal_reloaded
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Blick zwar schon lange nicht mehr was hier so diskutiert wird
aber immutables kenne ich ;)

Code: Alles auswählen

# Immutables ( unveränderbar )
# Unter anderem keine in-place modifikation möglich
"..." # Strings
1     # int 
1.2   # float

# Mutables ( veränderbare ) 
[]  # lists
{}  # dicts
So mal als Beispiel :)
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Zap hat geschrieben:Blick zwar schon lange nicht mehr was hier so diskutiert wird
aber immutables kenne ich ;)

Code: Alles auswählen

# Immutables ( unveränderbar )
# Unter anderem keine in-place modifikation möglich
"..." # Strings
1     # int 
1.2   # float

# Mutables ( veränderbare ) 
[]  # lists
{}  # dicts
So mal als Beispiel :)
Ach so,.....alles klar!

Danke!
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

rolgal_reloaded hat geschrieben:@BlackJack

...was meinst du jetzt mit immutables? - Beispiel?
Hi,

auch wenn ich nicht gefragt wurde:
http://dict.tu-chemnitz.de/dings.cgi?query=immutable hat geschrieben:unveränderbar; unveränderlich; unabänderlich {adj} <=> immutable
Unveränderliche Objekte in Python sind Strings, Integer, Long, Float, Tupel
Veränderliche Objekte sind Listen und Dictionaries.

Beispiele findest Du weiter oben im Thread.

Grüße,
der Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Man, das geht aber auch schnell hier... erst gestern immer auf das vorletzte Posting antwortet, heute schieben sich schon zwei dazwischen. :-)

Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

[/quote]
Unveränderliche Objekte in Python sind Strings, Integer, Long, Float, Tupel
Veränderliche Objekte sind Listen und Dictionaries.

Beispiele findest Du weiter oben im Thread.

Grüße,
der Michel[/quote]

Mann, ich Hirsch, weiss ich doch, aber immutables, also der englische Terminus war mir grad nicht geläufig-----

:roll: in Zukunft 5 Minuten nachdenken, bevor ich überflüssige Fragen stelle :D
Antworten