Rumah > Artikel > pembangunan bahagian belakang > Perlu berhati-hati apabila nilai lalai parameter fungsi Python ialah objek boleh ubah
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]
Bukankah ia sangat. novel, ia sebenarnya boleh dilakukan Dengan cara ini, kelajuannya benar-benar sangat pantas, dan hasil larian adalah seperti berikut:
Namun, saya menasihati anda untuk tidak melakukan ini , dan IDE juga akan menggesa anda bahawa tidak baik untuk berbuat demikian:
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]
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]
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)Keputusannya adalah seperti berikut:
140670243756736 [0, 1] 140670265684928 [1, 2, 0, 1, 2] 140670243756736 [0, 1, 0, 1]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_listDengan cara ini, jika nilai lalai my_list sentiasa []. Akhir sekaliSaya 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!