Heim >Backend-Entwicklung >Python-Tutorial >Wie übergebe ich eine Variable als Referenz?

Wie übergebe ich eine Variable als Referenz?

PHPz
PHPznach vorne
2024-02-09 20:00:05615Durchsuche

Wie übergebe ich eine Variable als Referenz?

Frageninhalt

Ich habe diesen Kurs zum Testen geschrieben:

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change(self.variable)
        print(self.variable)

    def change(self, var):
        var = 'Changed'

Wenn ich versuche, eine Instanz zu erstellen, ist die Ausgabe original。所以python中的参数似乎是按值传递的。那是对的吗?如何修改代码才能达到引用传递的效果,使得输出为changed?

Manchmal sind Leute überrascht von x = 1 这样的代码(其中 x 是参数名称)不会影响调用者的参数,但像 x[0] = 1 这样的代码却会影响调用者的参数。发生这种情况是因为尽管有 = wie Syntax, aber Item-Zuweisung und Slice-Zuweisung sind Methoden zur Mutationvorhandenen Objekten, anstatt Variablen neu zuzuweisen. Siehe Warum kann eine Funktion einige Parameter so ändern, wie sie vom Aufrufer wahrgenommen werden, andere jedoch nicht? Erfahren Sie mehr.

Siehe auch Was ist der Unterschied zwischen Referenzübergabe und Wertübergabe? Für wichtige, sprachunabhängige Terminologiediskussionen.


Die richtige Antwort

Parameter werden durch Zuweisung übergeben

. Dafür gibt es zwei Gründe:
  1. Der übergebene Parameter ist eigentlich eine Referenz
  2. auf das Objekt (die Referenz wird jedoch als Wert übergeben)
  3. Einige Datentypen sind veränderbar, andere jedoch nicht

Also:
  • Wenn Sie ein veränderliches

    Objekt an eine Methode übergeben, erhält die Methode einen Verweis auf dasselbe Objekt und Sie können es beliebig ändern. Wenn Sie sich jedoch innerhalb der Methode befinden, weiß der äußere Bereich nichts Danach wird die externe Referenz immer noch auf das ursprüngliche Objekt verweisen.
  • Wenn Sie ein unveränderliches

    Objekt an eine Methode übergeben, können Sie die externe Referenz immer noch nicht erneut binden oder das Objekt sogar ändern.

Um dies deutlicher zu veranschaulichen, geben wir einige Beispiele.

Liste – veränderlicher Typ

Versuchen wir, die an die Methode übergebene Liste zu ändern:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

Ausgabe:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']
outer_listDa es sich bei dem übergebenen Parameter um einen Verweis auf

und nicht um eine Kopie davon handelt, können wir ihn mithilfe der Mutationslistenmethode ändern und die Änderungen im äußeren Bereich widerspiegeln.

Jetzt wollen wir sehen, was passiert, wenn wir versuchen, die als Parameter übergebene Referenz zu ändern:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'english']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Ausgabe:

before, outer_list = ['we', 'like', 'proper', 'english']
got ['we', 'like', 'proper', 'english']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'english']
the_list 参数是按值传递的,因此为其分配新列表不会对方法外部的代码产生任何影响。 the_listouter_list 引用的副本,我们让 the_list 指向一个新列表,但无法更改 outer_listDa der Parameter the_list als Wert übergeben wird, hat die Zuweisung einer neuen Liste keine Auswirkungen auf den Code außerhalb der Methode. the_list ist eine Kopie dessen, worauf

verweist. Wir lassen the_list auf eine neue Liste verweisen, können aber nicht ändern, wohin

zeigt.

String – unveränderlicher Typ

Es ist unveränderlich, daher können wir den Inhalt der Zeichenfolge nicht ändern

Jetzt versuchen wir, die Referenz zu ändern

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'in a kingdom by the sea'
    print('set to', the_string)

outer_string = 'it was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Ausgabe: the_string 参数是按值传递的,因此为其分配新字符串不会对方法外部的代码看到任何影响。 the_stringouter_string 引用的副本,我们让 the_string 指向一个新字符串,但无法更改 outer_string

before, outer_string = it was many and many a year ago
got it was many and many a year ago
set to in a kingdom by the sea
after, outer_string = it was many and many a year ago

Noch einmal, aufgrund der

Punkte.

Ich hoffe, das macht die Sache klarer.

EDIT:

Jemand hat darauf hingewiesen, dass dies nicht die ursprüngliche Frage von @david beantwortet: „Kann ich irgendetwas tun, um die Variable als tatsächliche Referenz zu übergeben?“. Lasst uns hart arbeiten.

Wie lösen wir dieses Problem?

Wie die Antwort von @andrea zeigt, können Sie neue Werte zurückgeben. Dadurch ändert sich nichts an der Art und Weise, wie Inhalte weitergegeben werden, aber es ermöglicht Ihnen, die gewünschten Informationen zu erhalten:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

Wenn Sie die Verwendung des Rückgabewerts wirklich vermeiden möchten, können Sie eine Klasse erstellen, die Ihren Wert enthält, und ihn an die Funktion übergeben oder eine vorhandene Klasse verwenden, z. B. eine Liste:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])
🎜Obwohl das etwas mühsam erscheint. 🎜

Das obige ist der detaillierte Inhalt vonWie übergebe ich eine Variable als Referenz?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen