Heim  >  Artikel  >  Backend-Entwicklung  >  Seien Sie vorsichtig, wenn der Standardwert der Python-Funktionsparameter ein veränderbares Objekt ist

Seien Sie vorsichtig, wenn der Standardwert der Python-Funktionsparameter ein veränderbares Objekt ist

WBOY
WBOYnach vorne
2023-04-22 13:37:071228Durchsuche

Ich habe gesehen, dass variable Objekte an die Standardwerte von Python-Funktionsparametern übergeben werden, um die Rekursion der Fibonacci-Funktion zu beschleunigen. Der Code lautet wie folgt:

def fib(n, cache={0: 0, 1: 1}):
if n not in cache:
cache[n] = fib(n - 1) + fib(n - 2)
return cache[n]

Ist das nicht sehr neu, das kann tatsächlich sein Auf diese Weise ist die Geschwindigkeit wirklich sehr hoch. Die Laufergebnisse sind wie folgt:

小心此坑:Python 函数参数的默认值是可变对象

Ich rate Ihnen jedoch, dies nicht zu tun, und die IDE weist Sie auch darauf hin, dass dies schlecht ist:

小心此坑:Python 函数参数的默认值是可变对象

Das liegt daran, dass alles ein Objekt ist und Python-Funktionen auch Objekte sind und der Standardwert das Attribut des Objekts ist. Der Standardwert des Parameters ist bereits während der Kompilierungsphase an die Funktion gebunden Wenn es sich um ein Variablenobjekt handelt, wird der Standardwert des Python-Funktionsparameters gespeichert und von allen Aufrufern gemeinsam genutzt. Das heißt, wenn der Standardparameterwert einer Funktion ein Variablenobjekt wie List oder Dict ist und Aufrufer A Änderungen vornimmt Wenn Sie es verwenden, sieht Anrufer B beim Aufruf das geänderte Ergebnis von A. Ein solches Muster führt häufig zu unerwarteten Ergebnissen, wie der obige Fib-Algorithmus, ist jedoch eher ein Fehler.

Sie können sich diesen einfachen Code ansehen:

def func(n, li = []):
for i in range(n):
li.append(i)
print(l)

func(2) # [0,1]
func(3,l=[1,2]) # [1,2,0,1,2]
func(2) # [0,1]

Sie können zuerst die Ausgabe dieses Codes abschätzen, wenn er mit der in den Kommentaren übereinstimmt, dann liegen Sie falsch. Das korrekte Ergebnis ist:

[0, 1]
[1, 2, 0, 1, 2]
[0, 1, 0, 1]

Sie fragen sich vielleicht, warum die letzte Funktion (2) so ist. Keine Sorge, drucken wir (id(li)) aus, um sie zu debuggen:

def func(n, li = []):
print(id(li))
for i in range(n):
li.append(i)
print(li)

func(2)
func(3,li=[1,2])
func(2)

Das Ergebnis ist wie folgt:

140670243756736
[0, 1]
140670265684928
[1, 2, 0, 1, 2]
140670243756736
[0, 1, 0, 1]

Haben Sie es gefunden? Die IDs der ersten func(2) und der zweiten func(2) sind gleich, was darauf hinweist, dass sie dieselbe li verwenden. Dies bedeutet, dass der Standardwert des Parameters eine variable Objektlogik ist alle Anrufer Im Allgemeinen wird es geteilt.

Wenn Sie sich damit befassen möchten, warum Python so konzipiert ist, können Sie zu http://cenalulu.github.io/python/default-mutable-arguments/ gehen.

Wie kann man das vermeiden?

Der beste Weg besteht darin, keine veränderlichen Objekte als Funktionsstandardwerte zu verwenden. Wenn Sie es auf diese Weise verwenden müssen, finden Sie hier eine Lösung:

def generate_new_list_with(my_list=None, element=None):
if my_list is None:
my_list = []
my_list.append(element)
return my_list

Auf diese Weise, wenn der Standardwert von my_list immer [] ist.

Abschließend

Ich denke, die Implementierung der Fib-Funktion wird Sie vielleicht beeindrucken, aber bitte beachten Sie, dass eine solche Verwendung sehr gefährlich ist und nicht in Ihrem eigenen Code verwendet werden kann.

Das obige ist der detaillierte Inhalt vonSeien Sie vorsichtig, wenn der Standardwert der Python-Funktionsparameter ein veränderbares Objekt ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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