Perlu berhati-hati apabila nilai lalai parameter fungsi Python ialah objek boleh ubah

WBOY
Lepaskan: 2023-04-22 13:37:07
ke hadapan
1227 orang telah melayarinya

Saya melihat bahawa objek berubah dihantar ke nilai lalai parameter fungsi Python untuk mempercepatkan pengulangan fungsi Fibonacci Kodnya adalah seperti berikut:

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

Bukankah ia sangat. novel, ia sebenarnya boleh dilakukan Dengan cara ini, kelajuannya benar-benar sangat pantas, dan hasil larian adalah seperti berikut:

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

Namun, saya menasihati anda untuk tidak melakukan ini , dan IDE juga akan menggesa anda bahawa tidak baik untuk berbuat demikian:

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

Ini kerana semuanya adalah objek, dan fungsi Python juga merupakan objek parameter ialah atribut objek. Nilai lalai parameter sudah terikat pada fungsi semasa fasa kompilasi Jika ia adalah objek berubah, nilai lalai parameter fungsi Python akan disimpan dan dikongsi oleh semua pemanggil. Maksudnya, jika nilai lalai parameter fungsi ialah objek berubah-ubah, seperti Senarai atau Dict, pemanggil A Ubah suainya, maka pemanggil B akan lihat apabila memanggil ialah hasil diubah suai A. Mod sedemikian sering menghasilkan hasil yang tidak dijangka, seperti algoritma fib di atas, tetapi kebanyakannya adalah pepijat.

Anda boleh lihat kod ringkas ini:

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]
Salin selepas log masuk

Anda boleh menganggarkan output kod ini dahulu Jika ia sama dengan yang terdapat dalam ulasan, maka anda salah. Keputusan yang betul ialah:

[0, 1]
[1, 2, 0, 1, 2]
[0, 1, 0, 1]
Salin selepas log masuk

Anda mungkin tertanya-tanya mengapa func(2) terakhir begini, jangan risau, mari cetak(id(li)) untuk nyahpepijat:

<🎜. >
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)
Salin selepas log masuk
Keputusannya adalah seperti berikut:

140670243756736
[0, 1]
140670265684928
[1, 2, 0, 1, 2]
140670243756736
[0, 1, 0, 1]
Salin selepas log masuk
Adakah anda perasan bahawa id func(2) pertama dan func(2) kedua adalah sama, bermakna ia menggunakan li yang sama . Ini bermakna nilai lalai parameter ialah objek berubah-ubah, yang dikongsi oleh semua pemanggil.

Jika anda ingin mendalami mengapa Python direka bentuk seperti ini, anda boleh pergi ke http://cenalulu.github.io/python/default-mutable-arguments/

Bagaimana untuk mengelakkannya?

Cara terbaik ialah tidak menggunakan objek boleh ubah sebagai nilai lalai fungsi. Jika anda perlu menggunakannya dengan cara ini, berikut ialah penyelesaiannya:

def generate_new_list_with(my_list=None, element=None):
if my_list is None:
my_list = []
my_list.append(element)
return my_list
Salin selepas log masuk
Dengan cara ini, jika nilai lalai my_list sentiasa [].

Akhir sekali

Saya rasa pelaksanaan fungsi fib mungkin menarik perhatian anda, tetapi sila ambil perhatian bahawa penggunaan sedemikian sangat berbahaya dan tidak boleh digunakan dalam kod anda sendiri .

Atas ialah kandungan terperinci Perlu berhati-hati apabila nilai lalai parameter fungsi Python ialah objek boleh ubah. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:51cto.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan