Wann wirken sich Python-Funktionen auf die Argumente des Aufrufers aus?

Was wird im Argument der Python-Funktion übergeben? Wenn Sie es nicht wissen, zerstören Sie das ursprüngliche Objekt. Diese Zeit ist ein Experiment, um dies zu bestätigen. Die Version von Python ist 3.4.3.

Kopieren Sie das Array

In Python wirkt sich das Ändern der in einer Funktion übergebenen Argumente nicht auf die ursprünglichen Argumente aus.

mystr = "test"
myint = 100

def modify_str_and_int(mystr, myint):
    mystr = "after"
    myint = 200

modify_str_and_int(mystr, myint)
print("mystr = %s" % mystr)
print("myint = %s" % myint)

# =>
# mystr = test
# myint = 100

Die Verwendung eines Arrays als Argument wirkt sich auch auf das aufrufende Array aus. Daher ist es nicht erforderlich, das verarbeitete Array als Rückgabewert zurückzugeben.

mylist = ["foo","bar",100]
def modify_list(mylist):
    mylist.append("new")

print(mylist)
modify_list(mylist)
print(mylist)

['foo', 'bar', 100]
['foo', 'bar', 100, 'new']

Es gibt jedoch Zeiten, in denen Sie dies nicht ändern möchten. Zum Beispiel bei der Wiederverwendung des aufrufenden Arrays. Definieren Sie in diesem Fall eine neue Variable in der Funktion und verschieben Sie den Wert.

mylist = ["foo","bar",100]
def modify_list(mylist):
    new_list = mylist
    new_list.append("new")
    return new_list

print(mylist)
modify_list(mylist)
print(mylist)

# =>
# ['foo', 'bar', 100]
# ['foo', 'bar', 100, 'new']

Der ursprüngliche Wert wurde neu geschrieben. Dies liegt daran, dass Sie einen Verweis auf "new_list" übergeben, keine Kopie des Werts. Die beiden Variablen new_list und mylist zeigen also auf dasselbe Listenobjekt. Dies kann durch id bestätigt werden.

mylist = ["foo"]
new_list = mylist

print(id(mylist))
print(id(new_list))
print(id(mylist) == id(new_list))

# =>
# 4528474888
# 4528474888
# True

Erstellen wir also ein neues Listenobjekt mit demselben Wert wie "mylist". Die integrierte Funktionsliste ist eine Funktion zum Konvertieren eines Sequenztyps in eine Liste. Es ist jedoch auch möglich, ein neues Listenobjekt aus der Liste zu erstellen.

mylist = ["foo"]
new_list = list(mylist)

print(id(mylist))
print(id(new_list))
print(id(mylist) == id(new_list))

# =>
# 4313320328
# 4313327816
# False

Bei gleicher Verwendung in einer Funktion wirkt sich dies nicht auf das ursprüngliche Array aus.

mylist = ["foo","bar",100]
def modify_list(mylist):
    new_list = list(mylist)
    new_list.append("new")
    return new_list

print(mylist)
new_list = modify_list(mylist)
print(mylist)
print(new_list)

# =>
# ['foo', 'bar', 100]
# ['foo', 'bar', 100]
# ['foo', 'bar', 100, 'new']

Int und str werden ebenfalls als Referenz übergeben

Im ersten Beispiel, das ich gesehen habe, hatte das Ändern von int und str in der Funktion keinen Einfluss auf das ursprüngliche Objekt. Der Grund, warum das Array davon betroffen war, war, dass es auf dasselbe Objekt zeigte. Mit anderen Worten, die IDs der Objekte waren dieselben. Ist die ID dann für int und str unterschiedlich?

mystr = "test"
myint = 100

def modify_str_and_int(mystr, myint):
    print("mystr = %s" % id(mystr))
    print("myint = %s" % id(myint))

print("mystr = %s" % id(mystr))
print("myint = %s" % id(myint))
modify_str_and_int(mystr, myint)

# =>
# mystr = 4308535648
# myint = 4305807456
# mystr = 4308535648
# myint = 4305807456

Das? Beide sind gleich. Dies sollte sich auch auf den ursprünglichen Wert auswirken. Lass es uns erneut versuchen.

mystr = "test"
myint = 100

def modify_str_and_int(mystr, myint):
    mystr = "after"
    print("mystr = %s" % id(mystr))
    print("myint = %s" % id(myint))

print("mystr = %s" % id(mystr))
print("myint = %s" % id(myint))
modify_str_and_int(mystr, myint)

# =>
# mystr = 4557928800
# myint = 4555208800
# mystr = 4557705768
# myint = 4555208800

Das! ?? Dieses Mal hat nur mystr die ID geändert. Dies ist ein Umfangsproblem. Da Python alle Objekte sind, wird die ID des Objekts wie im Argument übergeben. Wenn dieselbe Variable in der Funktion neu definiert wird, ändert sich das Verhalten je nach Array und int oder str. Dieses Mal hat sich die ID von str geändert. Das Kriterium ist, ob das Objekt veränderlich (variabel) oder unveränderlich (unveränderlich) ist. Wenn es unveränderlich ist, wird ein Objekt mit demselben Wert erstellt, sodass sich die ID geändert hat.

Sie können sehen, dass derselbe ID-Wert an die Variable übergeben wird, auch wenn er sich nicht in der Funktion befindet. Ein Unterschied besteht darin, dass Sie auf sich selbst verweisen, wenn Sie denselben Argumentnamen verwenden. Innerhalb der Funktion wird die erste als neue Variable behandelt.

mystr = "test"
myint = 100
mylist = ['foo', 'bar']

new_str = mystr
new_int = myint
new_list = mylist

print(id(new_str) == id(mystr))
print(id(new_int) == id(myint))
print(id(new_list) == id(mylist))
# =>
# True
# True
# True

def display_outer():
    print("mystr = %s" % mystr)
    print("myint = %s" % myint)
    print("mylist = %s" % mylist)

display_outer()
# =>
# mystr = test
# myint = 100
# mylist = ['foo', 'bar']

Funktionen können sich auf äußere Variablen beziehen

Es stellt sich heraus, dass der ID-Wert so übergeben wird, wie er im Argument enthalten ist. Dies bedeutet, dass es möglich ist, auf die äußere Variable innerhalb der Funktion zu verweisen.

mystr = "test"
myint = 100
mylist = ['foo', 'bar']

def display_outer():
    print("mystr = %s" % mystr)
    print("myint = %s" % myint)
    print("mylist = %s" % mylist)

display_outer()
# =>
# mystr = test
# myint = 100
# mylist = ['foo', 'bar']

Recommended Posts

Wann wirken sich Python-Funktionen auf die Argumente des Aufrufers aus?
Schlüsselwortargumente für Python-Funktionen
Überprüfen Sie das Verhalten beim Zuweisen von Python
Was tun, wenn der Werttyp in Python nicht eindeutig ist?
Python-Funktionen
Übergeben von Argumenten beim Aufrufen von Python-Skripten über Blender in der Befehlszeile
# Python-Grundlagen (Funktionen)
[Anfänger] Python-Funktionen
Python Einfach zu bedienende Funktionen
Python-Grundlagen: Funktionen
Wann werden die Standardargumente in Python gebunden? Wenn die Variable im Abschluss gebunden ist, wird die Auswertung verschoben.
Was beim Nachahmen zu tun ist, wird in Python eingebettet
[Python of Hikari-] Kapitel 06-04 Funktionen (Argumente und Rückgabewerte 3)
Erhalten Sie das Formular in Python und führen Sie verschiedene Aktionen aus
Grundeinstellungen bei Verwendung der foursquare-API mit Python
(◎◎) {Lass Python die langweiligen Dinge machen) ......... (Hey? Lass uns Python die Hausaufgaben machen} (゜) (゜)
Python Gibt die Funktion an, die ausgeführt werden soll, wenn das Programm endet
Was tun, wenn "Name xxx nicht importiert werden kann" [Python]
Informationen zur Option --enable-shared beim Erstellen von Python unter Linux
[Python of Hikari-] Kapitel 06-03 Funktionen (Argumente und Rückgabewerte 2)
Um das Äquivalent von Rubys ObjectSpace._id2ref in Python zu tun
Wie viel kennen Sie die Grundlagen von Python?
Ich möchte am Ende etwas mit Python machen
Nicht überraschend bekannt! ?? Was ist mit den eingebauten Funktionsargumenten? Aus welcher Schule kommst du? [Python]
Effektives Python-Hinweiselement 20 Verwenden Sie None und die Dokumentationszeichenfolge, wenn Sie dynamische Standardargumente angeben