Dalam definisi metode berikut, untuk apa *
dan **
lakukan param2
?
def foo(param1, *param2):
def bar(param1, **param2):
Dalam definisi metode berikut, untuk apa *
dan **
lakukan param2
?
def foo(param1, *param2):
def bar(param1, **param2):
def func(*args)
). Untuk pertanyaan yang menanyakan apa artinya dalam panggilan fungsi (func(*[1,2])
) lihat di sini . Untuk pertanyaan yang menanyakan cara membuka paket argumen lihat di sini . Untuk pertanyaan yang menanyakan apa*
artinya dalam literal ([*[1, 2]]
) lihat di sini .Jawaban:
The
*args
dan**kwargs
merupakan idiom umum untuk memungkinkan sejumlah argumen untuk fungsi seperti yang dijelaskan dalam bagian ini lebih lanjut tentang mendefinisikan fungsi dalam dokumentasi Python.Ini
*args
akan memberi Anda semua parameter fungsi sebagai tuple :Itu
**kwargs
akan memberi Anda semua argumen kata kunci kecuali yang terkait dengan parameter formal sebagai kamus.Kedua idiom dapat dicampur dengan argumen normal untuk memungkinkan serangkaian argumen tetap dan beberapa variabel:
Mungkin juga untuk menggunakan ini sebaliknya:
Penggunaan lain dari
*l
idiom adalah untuk membongkar daftar argumen saat memanggil suatu fungsi.Dalam Python 3 dimungkinkan untuk digunakan
*l
di sisi kiri tugas ( Extended Iterable Unpacking ), meskipun itu memberikan daftar alih-alih tupel dalam konteks ini:Juga Python 3 menambahkan semantik baru (lihat PEP 3102 ):
Fungsi semacam itu hanya menerima 3 argumen posisi, dan semuanya setelahnya
*
hanya dapat diteruskan sebagai argumen kata kunci.sumber
**kwargs
sekarang sesuai dengan urutan argumen kata kunci diteruskan ke fungsi." - docs.python.org/3/whatsnew/3.6.html Bahkan, semua dikt dalam CPython 3.6 akan mengingat urutan penyisipan sebagai detail implementasi, ini menjadi standar dalam Python 3.7.got an unexpected keyword argument 'name'
Perlu juga dicatat bahwa Anda dapat menggunakan
*
dan**
saat memanggil fungsi juga. Ini adalah jalan pintas yang memungkinkan Anda untuk menyampaikan banyak argumen ke suatu fungsi secara langsung menggunakan daftar / tuple atau kamus. Misalnya, jika Anda memiliki fungsi berikut:Anda dapat melakukan hal-hal seperti:
Catatan: Kunci-kunci di dalam
mydict
harus diberi nama persis seperti parameter fungsifoo
. Kalau tidak, ia akan melemparTypeError
:sumber
Tunggal * berarti bahwa dapat ada sejumlah argumen posisi ekstra.
foo()
dapat dipanggil sepertifoo(1,2,3,4,5)
. Di dalam tubuh foo () param2 adalah urutan yang mengandung 2-5.Double ** berarti ada sejumlah parameter bernama tambahan.
bar()
dapat dipanggil sepertibar(1, a=2, b=3)
. Di dalam body bar () param2 adalah kamus yang berisi {'a': 2, 'b': 3}Dengan kode berikut:
outputnya adalah
sumber
foobar(param1, *param2, **param3)
untuk melengkapi jawaban ini.Mereka memungkinkan fungsi didefinisikan untuk menerima dan bagi pengguna untuk memberikan sejumlah argumen, posisi (
*
) dan kata kunci (**
).Mendefinisikan Fungsi
*args
memungkinkan sejumlah argumen posisi opsional (parameter), yang akan ditugaskan ke sebuah tuple bernamaargs
.**kwargs
memungkinkan sejumlah argumen kata kunci opsional (parameter), yang akan berada dalam nama yang ditentukankwargs
.Anda dapat (dan harus) memilih nama yang sesuai, tetapi jika maksudnya argumennya adalah semantik non-spesifik,
args
dankwargs
merupakan nama standar.Ekspansi, Melewati sejumlah argumen
Anda juga dapat menggunakan
*args
dan**kwargs
mengirimkan parameter dari daftar (atau setiap iterable) dan dicts (atau pemetaan apa pun), masing-masing.Fungsi menerima parameter tidak harus tahu bahwa mereka sedang diperluas.
Misalnya, xrange Python 2 tidak secara eksplisit berharap
*args
, tetapi karena dibutuhkan 3 bilangan bulat sebagai argumen:Sebagai contoh lain, kita dapat menggunakan ekspansi dict di
str.format
:Baru di Python 3: Menentukan fungsi dengan argumen hanya kata kunci
Anda dapat memiliki argumen hanya kata kunci setelah
*args
- misalnya, di sini,kwarg2
harus diberikan sebagai argumen kata kunci - tidak secara posisi:Pemakaian:
Juga,
*
dapat digunakan dengan sendirinya untuk menunjukkan bahwa hanya mengikuti kata kunci argumen, tanpa memungkinkan untuk argumen posisi tak terbatas.Di sini,
kwarg2
sekali lagi harus berupa argumen kata kunci yang dinamai secara eksplisit:Dan kami tidak dapat lagi menerima argumen posisi yang tidak terbatas karena kami tidak memiliki
*args*
:Sekali lagi, lebih sederhana, di sini kita perlu
kwarg
diberi nama, bukan secara posisi:Dalam contoh ini, kita melihat bahwa jika kita mencoba untuk melewati
kwarg
posisi, kita mendapatkan kesalahan:Kami harus secara eksplisit melewatkan
kwarg
parameter sebagai argumen kata kunci.Demo yang kompatibel dengan Python 2
*args
(biasanya dikatakan "star-args") dan**kwargs
(bintang dapat tersirat dengan mengatakan "kwargs", tetapi secara eksplisit dengan "kwarg bintang ganda") adalah idiom umum dari Python untuk menggunakan*
dan**
notasi. Nama-nama variabel spesifik ini tidak diperlukan (misalnya Anda bisa menggunakan*foos
dan**bars
), tetapi keberangkatan dari konvensi cenderung membuat marah sesama pembuat kode Python Anda.Kita biasanya menggunakan ini ketika kita tidak tahu apa fungsi kita akan menerima atau berapa banyak argumen yang mungkin kita lewati, dan kadang-kadang bahkan ketika penamaan setiap variabel secara terpisah akan menjadi sangat berantakan dan berlebihan (tetapi ini adalah kasus di mana biasanya eksplisit adalah lebih baik daripada implisit).
Contoh 1
Fungsi berikut menjelaskan bagaimana mereka dapat digunakan, dan menunjukkan perilaku. Perhatikan
b
argumen bernama akan dikonsumsi oleh argumen posisi kedua sebelum:Kami dapat memeriksa bantuan online untuk tanda tangan fungsi, dengan
help(foo)
, yang memberi tahu kamiMari kita panggil fungsi ini dengan
foo(1, 2, 3, 4, e=5, f=6, g=7)
yang mencetak:
Contoh 2
Kami juga dapat menyebutnya menggunakan fungsi lain, yang hanya kami sediakan
a
:bar(100)
cetakan:Contoh 3: penggunaan praktis dalam dekorator
OK, jadi mungkin kita belum melihat utilitasnya. Jadi bayangkan Anda memiliki beberapa fungsi dengan kode redundan sebelum dan / atau setelah kode pembeda. Fungsi bernama berikut ini hanya pseudo-code untuk tujuan ilustrasi.
Kami mungkin dapat menangani hal ini secara berbeda, tetapi kami dapat mengekstraksi redundansi dengan dekorator, dan contoh kami di bawah ini menunjukkan bagaimana
*args
dan**kwargs
bisa sangat berguna:Dan sekarang setiap fungsi yang dibungkus dapat ditulis lebih ringkas, karena kami telah memperhitungkan redundansi:
Dan oleh anjak keluar kode kita, yang
*args
dan**kwargs
memungkinkan kita untuk melakukan, kita mengurangi baris kode, lebih mudah dibaca dan rawatan, dan memiliki lokasi kanonik tunggal untuk logika dalam program kami. Jika kita perlu mengubah bagian mana pun dari struktur ini, kita memiliki satu tempat untuk membuat setiap perubahan.sumber
Mari kita pahami dulu apa itu argumen posisi dan argumen kata kunci. Di bawah ini adalah contoh definisi fungsi dengan argumen Posisional.
Jadi ini adalah definisi fungsi dengan argumen posisi. Anda dapat menyebutnya dengan argumen kata kunci / bernama:
Sekarang mari kita pelajari contoh definisi fungsi dengan argumen kata kunci :
Anda dapat memanggil fungsi ini dengan argumen posisional juga:
Jadi kita sekarang tahu definisi fungsi dengan argumen posisi dan kata kunci.
Sekarang mari kita pelajari operator '*' dan operator '**'.
Harap dicatat operator ini dapat digunakan di 2 area:
a) panggilan fungsi
b) definisi fungsi
Penggunaan operator '*' dan operator '**' dalam panggilan fungsi.
Mari kita langsung ke contoh dan mendiskusikannya.
Jadi ingatlah
ketika operator '*' atau '**' digunakan dalam panggilan fungsi -
Operator '*' membongkar struktur data seperti daftar atau tuple ke argumen yang diperlukan oleh definisi fungsi.
Operator '**' membongkar kamus ke dalam argumen yang diperlukan oleh definisi fungsi.
Sekarang mari kita pelajari penggunaan operator '*' dalam definisi fungsi . Contoh:
Dalam definisi fungsi , operator '*' mengemas argumen yang diterima menjadi tuple.
Sekarang mari kita lihat contoh '**' yang digunakan dalam definisi fungsi:
Dalam definisi fungsi, operator '**' mengemas argumen yang diterima ke dalam kamus.
Jadi ingat:
Dalam suatu fungsi panggil '*' membongkar struktur data tuple atau daftar ke argumen posisi atau kata kunci yang akan diterima oleh definisi fungsi.
Dalam suatu fungsi panggil '**' membongkar struktur data kamus ke dalam argumen posisi atau kata kunci yang akan diterima oleh definisi fungsi.
Dalam definisi fungsi , '*' mengemas argumen posisi menjadi tuple.
Dalam definisi fungsi , '**' mengemas argumen kata kunci ke dalam kamus.
sumber
Tabel ini berguna untuk menggunakan
*
dan**
dalam konstruksi fungsi dan panggilan fungsi :Ini benar-benar hanya berfungsi untuk meringkas jawaban Lorin Hochstein, tetapi saya merasa itu membantu.
Terkait: penggunaan untuk operator bintang / percikan telah diperluas di Python 3
sumber
*
dan**
memiliki penggunaan khusus dalam daftar argumen fungsi.*
menyiratkan bahwa argumen adalah daftar dan**
menyiratkan bahwa argumen adalah kamus. Ini memungkinkan fungsi untuk mengambil sejumlah argumen yang berubah-ubahsumber
Bagi Anda yang belajar melalui contoh!
*
adalah untuk memberi Anda kemampuan untuk mendefinisikan suatu fungsi yang dapat mengambil sejumlah argumen sewenang-wenang yang disediakan sebagai daftar (misalnyaf(*myList)
).**
adalah untuk memberi Anda kemampuan untuk memberi makan argumen fungsi dengan menyediakan kamus (misalnyaf(**{'x' : 1, 'y' : 2})
).Mari kita tunjukkan ini dengan mendefinisikan fungsi yang mengambil dua variabel yang normal
x
,y
dan dapat menerima lebih argumen sebagaimyArgs
, dan dapat menerima bahkan lebih argumen sebagaimyKW
. Nanti, kami akan menunjukkan cara memberi makany
menggunakanmyArgDict
.Peringatan
**
khusus disediakan untuk kamus.**
harus datang setelahnya*
, selalu.sumber
Dari dokumentasi Python:
sumber
*
berarti menerima argumen variabel sebagai tuple**
berarti menerima argumen variabel sebagai kamusDigunakan seperti berikut:
1) tunggal *
Keluaran:
2) Sekarang
**
Keluaran:
sumber
Saya ingin memberi contoh yang belum disebutkan orang lain
* juga dapat membongkar generator
Contoh dari Dokumen Python3
unzip_x akan menjadi [1, 2, 3], unzip_y akan menjadi [4, 5, 6]
Zip () menerima beberapa arg iretable, dan mengembalikan generator.
sumber
Dalam Python 3.5, Anda juga dapat menggunakan sintaks ini di
list
,dict
,tuple
, danset
menampilkan (juga kadang-kadang disebut literal). Lihat PEP 488: Generalisasi Pembongkaran Tambahan .Ini juga memungkinkan beberapa iterables dibongkar dalam satu panggilan fungsi.
(Terima kasih kepada mgilson untuk tautan PEP.)
sumber
Selain panggilan fungsi, * args dan ** kwargs berguna dalam hierarki kelas dan juga menghindari keharusan menulis
__init__
metode dengan Python. Penggunaan serupa dapat dilihat dalam kerangka kerja seperti kode Django.Sebagai contoh,
Subkelas kemudian bisa
Subkelas kemudian akan dipakai sebagai
Juga, subclass dengan atribut baru yang hanya masuk akal untuk instance subclass dapat memanggil kelas Basis
__init__
untuk menurunkan beban pengaturan atribut. Ini dilakukan melalui * args dan ** kwargs. kwargs terutama digunakan agar kode dapat dibaca menggunakan argumen bernama. Sebagai contoh,yang dapat dinegatifkan sebagai
Kode lengkapnya ada di sini
sumber
Membangun jawaban nickd ...
Keluaran:
Pada dasarnya, sejumlah argumen posisi dapat menggunakan * args dan argumen bernama apa pun (atau kwarg alias argumen kata kunci) dapat menggunakan ** kwargs.
sumber
*args
dan**kwargs
: memungkinkan Anda meneruskan sejumlah variabel argumen ke suatu fungsi.*args
: digunakan untuk mengirim daftar argumen panjang variabel non-kata kunci ke fungsi:Akan menghasilkan:
**kwargs*
**kwargs
memungkinkan Anda untuk meneruskan panjang variabel variabel yang di-kata kunci ke suatu fungsi. Anda harus menggunakan**kwargs
jika Anda ingin menangani argumen bernama dalam suatu fungsi.Akan menghasilkan:
sumber
Contoh ini akan membantu Anda mengingat
*args
,**kwargs
dan bahkansuper
dan warisan dalam Python sekaligus.sumber
Contoh yang baik menggunakan keduanya dalam suatu fungsi adalah:
sumber
TL; DR
Di bawah ini adalah 6 kasus penggunaan berbeda untuk
*
dan**
dalam pemrograman python:*args
:def foo(*args): pass
, di sinifoo
menerima sejumlah argumen posisional, yaitu, panggilan berikut adalah validfoo(1)
,foo(1, 'bar')
**kwargs
:def foo(**kwargs): pass
, di sini 'foo' menerima sejumlah argumen kata kunci, yaitu, panggilan berikut adalah validfoo(name='Tom')
,foo(name='Tom', age=33)
*args, **kwargs
:def foo(*args, **kwargs): pass
, di sinifoo
menerima sejumlah argumen posisional dan kata kunci, yaitu, panggilan berikut adalah validfoo(1,name='Tom')
,foo(1, 'bar', name='Tom', age=33)
*
:def foo(pos1, pos2, *, kwarg1): pass
, di sini*
berarti bahwa foo hanya menerima argumen kata kunci setelah pos2, makafoo(1, 2, 3)
menimbulkan TypeError tapifoo(1, 2, kwarg1=3)
ok.*_
(Catatan: ini hanya konvensi):def foo(bar, baz, *_): pass
berarti (dengan konvensi)foo
hanya menggunakanbar
danbaz
argumen dalam bekerja dan akan mengabaikan yang lain.\**_
(Catatan: ini hanya konvensi):def foo(bar, baz, **_): pass
berarti (dengan konvensi)foo
hanya menggunakanbar
danbaz
argumen dalam kerjanya dan akan mengabaikan yang lain.BONUS: Dari python 3.8 dan seterusnya, seseorang dapat menggunakan
/
definisi fungsi untuk menegakkan hanya parameter posisi. Dalam contoh berikut, parameter a dan b adalah hanya-posisi , sedangkan c atau d dapat berupa posisi atau kata kunci, dan e atau f diharuskan menjadi kata kunci:sumber
TL; DR
Itu paket argumen yang dilewatkan ke fungsi ke
list
dandict
masing - masing di dalam fungsi tubuh Ketika Anda mendefinisikan tanda tangan fungsi seperti ini:dapat dipanggil dengan sejumlah argumen dan argumen kata kunci. Argumen non-kata kunci dimasukkan ke dalam daftar yang disebut
args
di dalam badan fungsi dan argumen kata kunci dimasukkan ke dalam dict yang disebutkwds
di dalam bagian fungsi.sekarang di dalam tubuh fungsi, ketika fungsi dipanggil, ada dua variabel lokal,
args
yang merupakan daftar yang memiliki nilai["this", "is a list of", "non-keyword", "arguments"]
dankwds
yangdict
memiliki nilai{"keyword" : "ligma", "options" : [1,2,3]}
Ini juga bekerja secara terbalik, yaitu dari sisi penelepon. misalnya jika Anda memiliki fungsi yang didefinisikan sebagai:
Anda dapat memanggilnya dengan membongkar iterables atau pemetaan yang Anda miliki dalam lingkup panggilan:
sumber
Konteks
**
Gunakan dengan pemformatan string
Selain jawaban di utas ini, berikut adalah detail lain yang tidak disebutkan di tempat lain. Ini memperluas jawaban dari Brad Solomon
Membongkar dengan
**
juga berguna saat menggunakan pythonstr.format
.Ini agak mirip dengan apa yang dapat Anda lakukan dengan python
f-strings
f-string tetapi dengan overhead tambahan mendeklarasikan dict untuk menampung variabel (f-string tidak memerlukan dict).Contoh cepat
sumber
def foo(param1, *param2):
adalah metode dapat menerima jumlah nilai sewenang-wenang untuk*param2
,def bar(param1, **param2):
adalah metode dapat menerima jumlah nilai sewenang-wenang dengan kunci untuk*param2
param1
adalah parameter sederhana.Misalnya, sintaks untuk mengimplementasikan varargs di Java sebagai berikut:
sumber