Jika saya mendefinisikan metode kelas dengan argumen kata kunci sebagai berikut:
class foo(object):
def foodo(thing=None, thong='not underwear'):
print thing if thing else "nothing"
print 'a thong is',thong
memanggil metode menghasilkan TypeError
:
myfoo = foo()
myfoo.foodo(thing="something")
...
TypeError: foodo() got multiple values for keyword argument 'thing'
Apa yang sedang terjadi?
python
class
python-2.7
methods
drevicko
sumber
sumber
self
lebih baik daripada implisitthis
.Jawaban:
Masalahnya adalah bahwa argumen pertama yang diteruskan ke metode kelas dengan python selalu merupakan salinan dari instance kelas di mana metode ini dipanggil, biasanya diberi label
self
. Jika kelas dinyatakan demikian:berperilaku seperti yang diharapkan.
Penjelasan:
Tanpa
self
sebagai parameter pertama, ketikamyfoo.foodo(thing="something")
dijalankan,foodo
metode ini dipanggil dengan argumen(myfoo, thing="something")
. Contohmyfoo
kemudian ditugaskan untukthing
(karenathing
merupakan parameter pertama menyatakan), tetapi python juga upaya untuk menetapkan"something"
kething
, maka Eksepsi.Untuk menunjukkan, coba jalankan ini dengan kode asli:
Anda akan menghasilkan seperti:
Anda dapat melihat bahwa 'benda' telah diberi referensi ke instance 'myfoo' dari kelas 'foo'. Bagian dokumen ini menjelaskan cara kerja argumen fungsi sedikit lebih.
sumber
Terima kasih untuk posting instruktif. Saya hanya ingin mencatat bahwa jika Anda mendapatkan "TypeError: foodo () mendapat beberapa nilai untuk argumen kata kunci 'thing'", mungkin juga Anda keliru menyampaikan 'self' sebagai parameter saat memanggil fungsi (mungkin karena Anda menyalin garis dari deklarasi kelas - ini adalah kesalahan umum ketika seseorang sedang terburu-buru).
sumber
@classmethod
, solusinya adalah menggunakansuper().function(...)
alih-alih<parentclass>.function(cls, ...)
.Ini mungkin jelas, tetapi mungkin membantu seseorang yang belum pernah melihatnya sebelumnya. Ini juga terjadi untuk fungsi reguler jika Anda secara keliru menetapkan parameter berdasarkan posisi dan secara eksplisit berdasarkan nama.
sumber
cukup tambahkan dekorator 'staticmethod' agar berfungsi dan masalah telah diperbaiki
sumber
myfoo.foodo(thing="something")
, thing = "sesuatu" akan ditugaskan ke argumen pertama, daripada argumen diri implisit.self
Saya ingin menambahkan satu jawaban lagi:
there is difference between parameter and argument
Anda dapat membaca secara detail tentang di sini Argumen dan Parameter dalam pythonkarena kami memiliki tiga parameter:
a adalah parameter posisi
b = 1 adalah kata kunci dan parameter default
* args adalah parameter panjang variabel
jadi pertama-tama kita menetapkan parameter sebagai posisi, artinya kita harus memberikan nilai pada argumen posisi dalam urutan posisinya, di sini urutan penting. tapi kami melewati argumen 1 di tempat fungsi panggil dan kemudian kami juga memberikan nilai kepada, memperlakukan sebagai argumen kata kunci. sekarang a memiliki dua nilai:
satu adalah nilai posisi: a = 1
kedua adalah nilai kata kunci yang a = 12
Larutan
Kita harus berubah
hello(1, 2, 3, 4,a=12)
untukhello(1, 2, 3, 4,12)
jadi sekarang akan mendapatkan hanya satu nilai posisional yang 1 dan b akan mendapatkan nilai 2 dan beristirahat dari nilai-nilai akan mendapatkan * args (panjang variabel parameter)informasi tambahan
jika kita menginginkan * args harus mendapatkan 2,3,4 dan a harus mendapatkan 1 dan b harus mendapatkan 12
maka kita bisa melakukan ini
def hello(a,*args,b=1): pass hello(1, 2, 3, 4,b=12)
Sesuatu yang lebih :
keluaran:
sumber
Kesalahan ini juga dapat terjadi jika Anda memberikan argumen kata kunci yang salah satu kuncinya serupa (memiliki nama string yang sama) dengan argumen posisi.
"api" telah diterima dalam argumen 'bilah'. Namun ada argumen 'bar' lain yang hadir dalam kwargs.
Anda harus menghapus argumen kata kunci dari kwargs sebelum meneruskannya ke metode.
sumber
Juga ini bisa terjadi di Django jika Anda menggunakan jquery ajax untuk url yang membalikkan ke fungsi yang tidak mengandung parameter 'permintaan'
sumber