In python, die Rückgabe ein Objekt in einer Funktion Körper macht eine Tiefe Kopie?
Werde ich versuchen zu klären:
Zum Beispiel, ich mache eine Funktion, die lokal erstellt eine Liste und gibt es zurück. Wie funktioniert Python-erstellen der zurückgegebenen Liste, die sich außerhalb der Funktion Körper ? Ist es verwenden, "deepcopy" (oder so ähnlich) ?
In [50]: def create_list():
...: sublist1 = [1,2,3]
...: sublist2 = [4,5,6]
...: list_of_lists=[sublist1,sublist1,sublist2]
...: return list_of_lists
...:
In [51]: l=create_list()
In [52]: l
Out[52]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]]
In [53]: l[0].append(4)
In [54]: l
Out[54]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
Hier der zurückgegebenen Liste l
enthält noch die Teillisten. Und l[0]
und l[1]
noch verweisen auf das gleiche Unterverzeichnis (das ist das normale Python-Verhalten). Also die Liste und deren Struktur kopiert wurden.
Und wenn ich den Anruf mal wieder create_list()
:
In [55]: l2=create_list()
In [56]: l2
Out[56]: [[1, 2, 3], [1, 2, 3], [4, 5, 6]]
In [57]: l
Out[57]: [[1, 2, 3, 4], [1, 2, 3, 4], [4, 5, 6]]
Einer neuen Liste l2
erstellt wurde, aber l
ist unberührt, das heißt, es existiert außerhalb der Funktion, und seine unterlisten sind seine eigenen, keine Verweise auf Teillisten, die noch vorhanden sind in der Funktion Körper.
Also meine Frage : funktioniert die Python verwendet deepcopy oder etwas ähnliches zu machen l
?
Egal, welche Art von Objekt kehre ich mit einer Funktion, wird es unberührt von späteren Aufruf dieser Funktion ?
(so lange, wie das Objekt erstellt wurde lokal in der Funktion)
Zögern Sie nicht, mir zu sagen, wenn ich mich nicht klar genug ausgedrückt.
Danke,
- Nein, aber python macht neue Objekte erstellen jedes mal, wenn Sie eine Funktion auszuführen, bar passieren Sie einen änderbaren Standard-arg.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie die Funktion ausführen, das zweite mal die gesamte Funktion wird erneut ausgeführt, es hat keine Speicher entlang der Linien von "letztes mal
sublist1
war[1, 2, 3]
".Haben Sie nicht kopiert der Liste
[1, 2, 3]
. Sie haben erstellt es zweimal.Beachten Sie, dass wenn Sie einen caching-Dekorator wie
@functools.lru_cache
, erhalten Sie überraschende Ergebnisse:Weil in diesem Fall python hat eine Erinnerung an das Vorherige Ergebnis, und gibt das gleiche Objekt zurück
def f(l=[]):
verfolgt, zwischen verschiedenen aufrufen zuf
. Also die Standard-Parameter sind konstruiert, nur einmal, wenn die Funktion definiert ist, aber seine lokalen Werte werden nur gebaut, wenn es aufgerufen wird (und somit für jeden anders nennen) ?@lru_cache()
ich verstehen, dass es caches vorherigen Funktion aufruft, also beim zweiten Aufruf, sieht er, dass ein Anruf getätigt wurde mit den gleichen Argumenten (d.h. keine), also einfach den Rückgabewert des ersten Aufrufs (was geändert wurde in zwischen durch diel[0].append(4)
) ? Ich will einfach nur, um sicherzustellen, dass ich verstehe.()
, nichtNone
.Dies vielleicht nicht direkt diese Frage zu beantworten, sondern sollte helfen, zu klären Verwandtes Konzept.
Wenn Sie erstellen Sie eine verschachtelte Objekt innerhalb einer Funktion und gibt es zurück, das Objekt weiter zu existieren. Es würde nicht gehen out-of-scope-auch wenn die Funktion beendet.
Beispiel-Code
Ausgabe
Einem dict,
dict_x
zugeordnet istprop_x
variable von einem Objekt der Klasseobj1
. Das dict wird nicht erstellt, wieder in Erinnerung, aber einsoft copy
stattfindet.prop_x
Punkte, um die Speicherpositiondict_x
.Zurückkehren, wenn Sie Objekt
obj1
am Ende dieser Funktiondict_x
geht out of scope, aber die Speicher-Adresse verwendet, durch0xdfaae0
, noch zeigteprop_x
im zurückgegebenen Objektrecv_obj
. So, die dict-Werte{ "k1" : "v1" }
sind im Gedächtnis bewahrt.dict_x
Adresse war0x2ff5540
,prop_x
- Adresse ist0x35c5540
. Wie sagt manprop_x
Punkte auf das gleiche Objekt wiedict_x
(im heap)? Können Sie bitte erklären, vielleicht bin ich etwas fehlt..Variablen in Python sind Zeiger auf Objekte. So eine Funktion gibt einen Zeiger auf ein Objekt angelegt, in der Funktion, so dass kein Bedarf für das kopieren, die Werte zurückgeben.
sublist
war immer an die gleiche Adresse im Speicher, aber es war nicht der Fall.