Wie kann ich in Python eine Ganzzahl als Referenz übergeben?
Ich möchte den Wert einer Variablen ändern, die ich an die Funktion übergebe. Ich habe gelesen, dass alles in Python als Wert übergeben wird, aber es muss einen einfachen Trick geben. Zum Beispiel in Java könnten Sie die Referenztypen passieren Integer
, Long
usw.
- Wie kann ich eine Ganzzahl als Referenz an eine Funktion übergeben?
- Was sind die Best Practices?
python
function
pass-by-reference
pass-by-value
CodeKingPlusPlus
quelle
quelle
Antworten:
In Python funktioniert das nicht ganz so. Python übergibt Verweise auf Objekte. Innerhalb Ihrer Funktion haben Sie ein Objekt - Sie können dieses Objekt (wenn möglich) mutieren. Ganzzahlen sind jedoch unveränderlich . Eine Problemumgehung besteht darin, die Ganzzahl in einem Container zu übergeben, der mutiert werden kann:
Das ist bestenfalls hässlich / ungeschickt, aber in Python werden Sie es nicht besser machen. Der Grund dafür ist, dass Zuweisung (
=
) in Python jedes Objekt nimmt, das das Ergebnis der rechten Seite ist, und es an alles bindet, was sich auf der linken Seite befindet * (oder es an die entsprechende Funktion übergibt).Wenn wir dies verstehen, können wir sehen, warum es keine Möglichkeit gibt, den Wert eines unveränderlichen Objekts innerhalb einer Funktion zu ändern. Sie können keines seiner Attribute ändern, weil es unveränderlich ist, und Sie können der "Variablen" nicht einfach eine neue zuweisen Wert, weil Sie dann tatsächlich ein neues Objekt erstellen (das sich vom alten unterscheidet) und ihm den Namen geben, den das alte Objekt im lokalen Namespace hatte.
Normalerweise ist die Abhilfe einfach zurückgeben das Objekt , das Sie wollen:
* Im ersten Beispielfall oben wird
3
tatsächlich an übergebenx.__setitem__
.quelle
C
. (Sie müssen zum Beispiel nicht dereferenziert werden). In meinem mentalen Modell ist es einfacher, sich Dinge als "Namen" und "Objekte" vorzustellen. Die Zuweisung bindet einen oder mehrere "Namen" links an einen oder mehrere "Objekte" rechts. Wenn Sie eine Funktion aufrufen, übergeben Sie das "Objekt" (binden es effektiv an einen neuen lokalen Namen innerhalb der Funktion)..
Bediener dereferenziert einfach die linke Seite. Operatoren können in verschiedenen Sprachen unterschiedlich sein.In den meisten Fällen, in denen Sie als Referenz übergeben müssten, müssen Sie mehr als einen Wert an den Anrufer zurückgeben. Eine "Best Practice" ist die Verwendung mehrerer Rückgabewerte, was in Python viel einfacher ist als in Sprachen wie Java.
Hier ist ein einfaches Beispiel:
quelle
Einen Wert nicht genau direkt übergeben, sondern so verwenden, als ob er übergeben worden wäre.
Vorsichtsmaßnahmen:
nonlocal
wurde in Python 3 eingeführtglobal
anstelle vonnonlocal
.quelle
Die beste Vorgehensweise besteht darin, einen Schritt zurückzutreten und zu fragen, ob Sie dies wirklich tun müssen. Warum möchten Sie den Wert einer Variablen ändern, die Sie an die Funktion übergeben?
Wenn Sie es für einen schnellen Hack tun müssen, ist der schnellste Weg, eine
list
Ganzzahl zu halten und[0]
bei jeder Verwendung eine Ganzzahl zu verwenden, wie die Antwort von mgilson zeigt.Wenn Sie es für etwas größere Bedeutung zu tun brauchen, schreiben Sie ein ,
class
die eine hatint
als Attribut, so dass Sie es einfach einstellen. Dies zwingt Sie natürlich dazu, einen guten Namen für die Klasse und das Attribut zu finden. Wenn Ihnen nichts einfällt, lesen Sie den Satz einige Male erneut und verwenden Sie dann denlist
.Wenn Sie versuchen, eine Java-Sprache direkt nach Python zu portieren, machen Sie das im Allgemeinen falsch. Selbst wenn etwas direkt korrespondiert (wie bei
static
/@staticmethod
), möchten Sie es in den meisten Python-Programmen nicht verwenden, nur weil Sie es in Java verwenden würden.quelle
In Python ist jeder Wert eine Referenz (ein Zeiger auf ein Objekt), genau wie bei Nicht-Grundelementen in Java. Ebenso wie Python hat Python nur einen Wert für die Übergabe. Semantisch gesehen sind sie also ziemlich gleich.
Da Sie Java in Ihrer Frage erwähnen, würde ich gerne sehen, wie Sie das erreichen, was Sie in Java wollen. Wenn Sie es in Java zeigen können, kann ich Ihnen zeigen, wie es in Python genau gleichwertig gemacht wird.
quelle
Ein numpy Einzelelement-Array ist veränderlich und kann dennoch für die meisten Zwecke ausgewertet werden, als wäre es eine numerische Python-Variable. Daher ist es ein bequemerer Container für Referenznummern als eine Liste mit einzelnen Elementen.
Ausgabe:
quelle
Vielleicht ist es nicht pythonisch, aber Sie können dies tun
quelle
quelle
Vielleicht etwas selbstdokumentierender als der Trick mit der Liste der Länge 1 ist der alte Trick mit dem leeren Typ:
quelle
In Python wird alles als Wert übergeben. Wenn Sie jedoch einen Status ändern möchten, können Sie den Wert einer Ganzzahl in einer Liste oder einem Objekt ändern, das an eine Methode übergeben wird.
quelle
everything is passed by value
das nicht wirklich stimmt. Zitat docs:arguments are passed using call by value (where the value is always an object reference, not the value of the object)