2017-04-19 2 views
1

Dies ist eine einfache Frage, aber ich konnte keine ähnliche in SO finden. Ist die Rückgabe per Referenz in Python überhaupt verfügbar? (Vielleicht mit einfachen Hacks.)Rücksendung per Referenz möglich?

Return durch Verweis Erklärung:

def func(lst): 
    return reference of lst[2] somehow 

func([7, 8, 9, 10])  # returns 9 
func([7, 8, 9, 10]) = 11 # lst is changed to [7, 8, 11, 10] 

Ist dieses Verhalten erreichbar? Vielleicht mit Überlastung eines Bedieners?

Ein Beispiel für diese Verwendung in C++: Returning values by reference in C++

+0

@abccd Nun ist es möglich, in C++, fragte ich mich, wenn es in Python möglich war. – Rockybilly

+0

nicht so etwas wie "Rückkehr durch Referenz", vielleicht meinen Sie "Anruf per Referenz"? – muratgu

+2

Nicht genau. Dies funktioniert nur mit einem veränderbaren Objekt (Liste, Wörterbuch, etc ..) –

Antwort

0

Nr = in Python erneut bindet, so dass Sie nicht eine C++ zurückgeben können - Artreferenz. Und Python Slicing Kopien, also versucht, eine list Scheibe zurückgeben und zuweisen, hat keinen Einfluss auf die ursprüngliche Liste.

Die nächstgelegene Sie ohne extreme Maßnahmen bekommen könnte, wäre den Index zurück, und lassen Sie den Anrufer es verwenden, um neu zuzuweisen, z.B .:

def func(lst): 
    return ... some computed index, e.g. 2 ... 

mylist = [7, 8, 9, 10] 
mylist[func(mylist)]  # Gets 9 
mylist[func(mylist)] = 11 # mylist is changed to [7, 8, 11, 10] 

Das ist schrecklich Code obwohl; In der Regel schreiben Sie eine Funktion, die entweder eine neue, mutierte list (Original unverändert) zurückgibt oder eine list an Ort und Stelle mutiert (keine Rückgabe, implizit None).

2

Was sollten Sie wahrscheinlich tun, ist nur 2 zurückkehren und dann verwenden, die als Index in die Liste, die Sie in geben:

lyst = [7, 8, 9, 10] 
def func(lst): 
    # ... 
    return 2 

lyst[func(lyst)] = 11 

Sie können ein Objekt erstellen, die einen Verweis auf den Behälter kapselt plus Index (oder Schlüssel im Fall eines Wörterbuchs) des jeweiligen Elements:

class ElementRef(object): 

    def __init__(self, obj, key): 
     self.obj = obj 
     self.key = key 

    @property 
    def value(self): return self.obj[self.key] 

    @value.setter 
    def value(self, value): self.obj[self.key] = value 

dann Ihre Funktion wie folgt aussieht:

def func(lyst): 
    # ... 
    return ElementRef(lyst, 2) 

Und Sie können, indem sein value Attribut wie dies das Element ändern:

func(lyst).value = 11 

Aber ich weiß nicht viel Wert in dieser über gerade zurückkehr den Index sehen. Vor allem, weil das Objekt nutzlos werden kann, wenn Elemente vor der Verwendung zu der Liste hinzugefügt oder aus ihr entfernt werden. Das explizite Zurückgeben eines Indexes macht dies zu einem offensichtlichen Problem, aber wenn Sie eine ElementRef zurückbekommen, können Sie annehmen, dass sie eine Art von Magie enthält, die sie nicht enthält.

+0

Heh. War im Begriff, ähnlich zu meiner Antwort zu bearbeiten, aber ich denke, dass sie besser als getrennte Antworten arbeiten, also werde ich Doppelarbeit vermeiden. Wenn Sie noch etwas weiter gehen möchten, könnten Sie 'ElementRef' zu einer Proxy-style-Klasse machen (über' __getattr__' oder Ähnliches), so dass Sie den referenzierten Wert nicht nur ändern, sondern auch als zugrunde liegenden Typ verwenden können. Nicht wirklich die Mühe wert, nur erwähnt es als "wenn Sie schrecklich Python schreiben wollen, weil Sie ein Masochist" -Option sind. :-) Trotzdem abgestimmt. – ShadowRanger

0
def func(lst): 
    return reference of lst[2] somehow 

Wenn Sie das tun:

def func(lst): 
    return lst[2] 

a = [1, 2, [3]] 
b = func(a) 

dann bist ein Verweis auf a[2]. Genauer gesagt sind sowohl b als auch a[2] Verweise auf dasselbe Listenobjekt ([3]).

Daher

b.append(4) 
print(a) # --> [1, 2, [3, 4]] 

Aber Sie müssen verstehen, dass der Zuweisungsoperator = in Python nicht die linke Seite mutiert, weist es nur einen neuen Namen zu der rechten Seite.

+0

Können Sie Dokumentation bereitstellen? – Adrian

+0

@Adrian Die Antworten und verknüpften externen Ressourcen dieser Frage sind ziemlich umfassend: https://stackoverflow.com/questions/986006/how-doi-i-pass-a-variable-by-reference – mkrieger1

0

Sie können auch etwas tun, wie dies durch die Zuordnung als Argument für die Funktion übergeben, da Python nicht C unterstützt ++ Werte durch Verweis Rückkehr:

def func(lst, change_val = None): 
    if change_val is not None: 
     lst[2] = change_val 
    return lst[2] 
lst = [7, 8, 9, 10] 
print(func(lst))  # prints 9 
print(func(lst, 11)) # prints 11; lst is changed to [7, 8, 11, 10] 
print(lst) # prints [7, 8, 11, 10] since it was changed before 
Verwandte Themen