Parameterübergabe als Pointer

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
Volker Schulte
User
Beiträge: 20
Registriert: Sonntag 8. Februar 2009, 10:23
Wohnort: Lüdenscheid

Hallo

Ich möchte ein (Pygame)Surface an eine Klasse/Methode als Zeichenbereich übergeben, die diesen komplett verwalten kann (also verändern) und ggf. neuzeichnen.

Zu diesem Zweck möchte das Haupt-Surface (Bildschirm) als Pointer in eine Klasse übergeben, damit diese weiss, was sie als Zeichenfläche benutzen kann.

Ich habe aber keine Ahnung, wie man verhindern kann, dass dieser Parameter zu einer neuen Variable wird und damit den Bezug zur Ursprünglichen verliert.

Diese sollte wirklich der Originalvariable entsprechen, damit ich diese verändern kann und im "Hauptprogramm" weiterverwenden kann.

Bin auch für andere Lösungsmöglichkeiten offen, möchte allerdings von globalen Variablen absehen.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

BlackJack hat geschrieben:Was meinst Du mit "ohne Kopien anzufertigen"? "Fertige" einfach keine an, sondern übergibt das Objekt. Python kopiert Objekte nie implizit.
(Quelle: http://www.python-forum.de/post-134555.html#134555)
Volker Schulte
User
Beiträge: 20
Registriert: Sonntag 8. Februar 2009, 10:23
Wohnort: Lüdenscheid

Hier ein kleines Beispiel mit Integervariablen anstatt Surfaces zur Verdeutlichung:

Code: Alles auswählen

class test:
    def __init__(self):
        pass
    def u(self,s):
        print "ID vor Wertezuweisung s: ",id(s)
        s = 14
        print "ID nach Wertezuweisung s: ",id(s)

    
z = 12
t=test()
print "Vor Aufruf der Methode ", id(z)
t.u(z)
print "Nach Aufruf der Methode ",id(z)
# nun möchte ich dass z dem Wert aus der Methode entspricht (z=14)!!!!
Rückgabe:
Vor Aufruf der Methode 24204284
ID vor Wertezuweisung s 24204284
ID nach Wertezuweisung s 24204260
Nach Aufruf der Methode 24204284

Die ID ist nicht mehr die gleiche und somit handelt es sich nicht mehr um das gleiche Objekt, sobald der Wert s überschrieben wird. Das gleiche auch, wenn ich " self.s =s " schreibe. Dieses soll aber nicht der Fall sein.
Benutzeravatar
snafu
User
Beiträge: 6741
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Bei Klassen passiert das aber nicht:

Code: Alles auswählen

In [5]: class Foo(object):
   ...:     def change(self, cls):
   ...:         cls.z = 14
   ...:         
   ...:         

In [6]: class Bar(object): pass
   ...: 

In [7]: bar = Bar()

In [8]: bar.z = 12

In [9]: foo = Foo()

In [10]: foo.change(bar)

In [11]: bar.z
Out[11]: 14
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Volker Schulte hat geschrieben:Bin auch für andere Lösungsmöglichkeiten offen, möchte allerdings von globalen Variablen absehen.
Im Prinzip geht es dir aber doch darum, etwas zu realisieren, was man mittels global erreichen würde - nur eben ohne global. :wink:

Was spricht denn dagegen, die zu verändernden Daten als Parameter zu übernehmen und den geänderten Wert als Rückgabewert zurück zu liefern?

Ansonsten wäre eine - von mir aber nicht empfohlene - Möglichkeit, die zu verändernden Daten in eine Liste zu verpacken und diese als Parameter zu übergeben. Änderungen an der Liste innerhalb der Funktion wirken sich dann auch "nach außen" aus.
BlackJack

@Volker Schulte: Das was Du willst geht nicht. Python hat keine Zeiger und Namen sind keine Namen für Speicherstellen, sondern für Objekte.

Das ist nicht das Variablenmodell aus zum Beispiel C, wo ein Name eine Box beschreibt, wo man einen Wert hinein tun kann, sondern Namen sind wie Post-It-Zettel, die an Objekte geklebt werden. Wenn man in C einem Namen etwas zuweist, dann wird ein Wert in die Schachtel mit dem Namen getan. Bei Python wird der Zettel mit dem Namen an ein anderes Objekt geklebt. Eine Zuweisung an *einen* Namen, verändert nie die Bindung von anderen Namen an die Objekte an denen sie kleben.

In Deinem Beispiel hast Du den Namen `z` an die 12 geklebt. Beim Funktionsaufruf wurde dann an die 12 noch der Zettel `s` geklebt. Und dann wurde der Zettel `s` von der 12 abgezogen und an die 14 geklebt. Das Zettelchen mit `z` klebt weiterhin an der 12.
Volker Schulte
User
Beiträge: 20
Registriert: Sonntag 8. Februar 2009, 10:23
Wohnort: Lüdenscheid

Vielen Dank für eure Bemühungen. Ich wusste nicht, dass sich ein Surface(Objekt) anders verhält als eine Integervariable.

Habe das jetzt einfach mit Surfaces ausprobiert und es funktioniert.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Volker Schulte hat geschrieben:Vielen Dank für eure Bemühungen. Ich wusste nicht, dass sich ein Surface(Objekt) anders verhält als eine Integervariable.
Nein, in Python verhalten sich alle Objekte gleich (von einigen sehr speziellen Sachen bei den builtin-Typen). Es ist nur so, dass

Code: Alles auswählen

foo = bar
konzeptionell etwas völlig anders als

Code: Alles auswählen

foo.baz = bar
ist. Das letztere entsprich einem

Code: Alles auswählen

setattr(foo, "baz", bar)
. Wie du siehst wird dabei keiner Variable ein neuer Wert zugewiesen.
Antworten