Frage 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.
Antworten
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Ich lade mir meine Spriteklasse in eine Variable:

Code: Alles auswählen

        self.diagreen = Sprite('gfx/sprites/diagreen.json', 'gfx/sprites/diagreen.png')
Nun habe ich das Sprite in self.diagreen also die Instanz von meiner Spriteklasse. So weit, so gut, es wird auch alles richtig angezeigt. Jetzt möchte ich in einer Schleife, sagen wir 10 mal die Variable self.diagreen in eine Liste packen:

Beispiel 1:

Code: Alles auswählen

	self.spritemap = [] 
        for i in range(1, 10)):
        	self.spritemap.append(self.diagreen)
Jetzt wird allerdings immer nur das erste Sprite angezeigt, die restliche fehlen also es wird kein Image angezeigt. Mache ich es allerdings so:

Beispiel 2:

Code: Alles auswählen

	self.spritemap = [] 
        for i in range(1, 10)):
        	self.spritemap.append(copy.copy(self.diagreen))
Wird alles richtig angezeigt. Das kann aber doch so nicht richtig sein. Eigentlich sollte ich doch ohne Probleme self.diagreen in eine Liste einfügen können ohne eine Kopie. Mache ich da irgend etwas falsch? Mein Vorhaben ist ja, 10 mal das gleiche Sprite in eine Liste zu bekommen.
Benutzeravatar
kbr
User
Beiträge: 1501
Registriert: Mittwoch 15. Oktober 2008, 09:27

Im ersteren Fall erzeugst Du zehn Referenzen auf eine Sprite-Instanz, im zweiten Fall zehn Referenzen auf zehn Sprite-Instanzen. Daher der Unterschied.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@kbr:
Ich kann Dir nicht ganz folgen. Müßte Beispiel 1 denn nicht richtig sein? Oder mal so gefragt, wie würdest du 10 mal self.diagreen in eine Liste packen?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@The Hit-Man

Diese Zeile enthält einen SyntaxError

Code: Alles auswählen

for i in range(1, 10)):
Es würde mich wundern wenn das überhaupt lauffähig ist. (Vielleicht beim Kopieren passiert?)

Ich weiß leider nicht, wie genau deine Klassen aussehen, aber bei "normalen" Klassen dürfte der einzige Unterschied darin bestehen, dass beim ersten Mal zehn Referenzen auf das selbe Objekt in die Liste gepackt werden und beim zweiten mal durch "copy" jeweils eine Referenz auf eine Kopie des Objektes in die Liste gepackt wird.


Der folgende Code zeigt ein Bespiel:

Code: Alles auswählen

import copy

class AClass:
    pass

a_instance = AClass()
a_instances_first = []
a_instances_second = []

for i in range(2):
    a_instances_first.append(a_instance)
    a_instances_second.append(copy.copy(a_instance))

for instance in a_instances_first:
    print(instance)

print()

for instance in a_instances_second:
    print(instance)
Ausgabe:

Code: Alles auswählen

<__main__.AClass object at 0x000002AA2EF4F820>
<__main__.AClass object at 0x000002AA2EF4F820>

<__main__.AClass object at 0x000002AA2EF4F8B0>
<__main__.AClass object at 0x000002AA2EF4F8E0>
Wie man sieht werden jeweils 2 Referenzen erzeugt, beim zweiten Mal aber an unterschiedlichen Addressen.

Falls sich das bei dir anders verhält müsstest du vielleicht mal zeigen, wie genau die Klassen aufgebaut sind
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

ok, das habe ich glaube ich verstanden. Es geht wohl weniger um meine Spriteklasse ...
Das ist ja eher, was ich brauche/suche. Wenn du jetzt in AClass zum Beispiel ein Image laden würdest dann müßte doch das image hier mit drin stehen:

a_instances_first[0] und a_instances_first[1] und a_instances_first[2]

Code: Alles auswählen


class AClass:
    def __init__ ():
        lade_imge = lade das image von festplatte ()

a_instance = AClass()
a_instances_first = []

for i in range(2):
    a_instances_first.append(a_instance)

for instance in a_instances_first:
    print(instance)

print()
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Es ist schwierig über Code zu reden, der nicht lauffähig ist.
Bei der init-Methode fehlt das 'self'
Bei diesem Beispiel ist "lade_imge" eine lokale Variable, die nur in der init-Methode bekannt ist. Darauf wird man also später nicht zugreifen können.
Außerdem werden nur 2 Instanzen erzeugt. a_instances_first[2] gibt es nicht.

Aber mal abgesehen von diesen Fehlern hast du Recht und du solltest mehrere Referenzen auf das gleiche Objekt in der Liste haben.

Ich glaube es ist aber besser, wenn du ein reduziertes Beispiel deines Codes postest, welches den Fehler darstellt, ohne gleich alles zu posten.
Versuch bitte ein kleines lauffähiges Programm zu erzeugen, was uns den Fehler zeigt.
Sonst kann man nur raten...
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

aaah, warte mal ... Das ist dann immer das selbe Objekt? Ich denke, da liegt bei mir der Fehler. Ich müßte ja immer ein neues haben.
Ach und klar, vor dem lade_image, natürlich ein self vor, damit ich drauf zu greifen kann. Glaube dann, ich habe den Fehler, gleich mal ausprobieren.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Alles klar, danke für die Denkanstöße! Hat dann geklappt.
Das Problem war, das ich davon ausging wenn ich self.diagreen also die Instanz in das Listfeld per append mit nehme, das ich immer eine neue Instanz bekommen hätte. Habe ich ja dann nicht, sondern immer das gleiche Objekt ( sprite ). Das war der Fehler.
Antworten