Argumen normal vs. argumen kata kunci

289

Apa perbedaan "argumen kata kunci" dari argumen biasa? Tidak bisakah semua argumen diteruskan sebagai name=valueganti menggunakan sintaksis posisi?

mk12
sumber
6
Anda mungkin juga ingin membaca PEP 3102 - mereka merapikan beberapa hal ini dengan Python 3. Lihat: python.org/dev/peps/pep-3102
Ben Hoyt
Dan apakah ada atau tidak nilai default tidak ada hubungannya dengan itu (kecuali apakah Anda perlu memberikan nilai untuk itu atau tidak), kan?
mk12
Baca lebih lanjut tentang argumen posisi / kata kunci python
ducin
@ Ben Hoyt Menambahkan jawaban di bawah ini yang mencakup Python 3, diperlukan argumen kata kunci
Christophe Roussy

Jawaban:

346

Ada dua konsep terkait, keduanya disebut " argumen kata kunci ".

Di sisi panggilan, yang disebutkan oleh komentator lain, Anda memiliki kemampuan untuk menentukan beberapa argumen fungsi berdasarkan nama. Anda harus menyebutkannya setelah semua argumen tanpa nama ( argumen posisional ), dan harus ada nilai default untuk parameter apa pun yang tidak disebutkan sama sekali.

Konsep lainnya ada di sisi definisi fungsi: Anda dapat mendefinisikan fungsi yang mengambil parameter berdasarkan nama - dan Anda bahkan tidak harus menentukan apa nama-nama itu. Ini adalah argumen kata kunci murni , dan tidak dapat disampaikan secara posisi. Sintaksnya adalah

def my_function(arg1, arg2, **kwargs)

Setiap argumen kata kunci yang Anda masukkan ke fungsi ini akan ditempatkan ke dalam kamus yang bernama kwargs. Anda dapat memeriksa kunci kamus ini saat run-time, seperti ini:

def my_function(**kwargs):
    print str(kwargs)

my_function(a=12, b="abc")

{'a': 12, 'b': 'abc'}
Ian Clelland
sumber
5
+1 dan diterima: Anda adalah satu-satunya yang berbicara tentang kedua jenis argumen posisi + kata kunci, semua orang berpikir saya sedang berbicara tentang yang pertama atau yang kedua (tetapi mereka masih posting yang bagus). Terima kasih!
mk12
34
Kata-katanya tidak jelas: Biasanya Anda berbicara tentang argumen di sisi panggil sementara parameter di sisi yang dipanggil.
glglgl
3
Apakah nama parameter harus kwargsatau saya dapat mengubah nama menjadi sth. suka options( def my_fuction(arg1, arg2, **options))?
Bruce Sun
1
Namanya bisa apa saja, meskipun itu kwargsadalah konvensi ketika tidak ada nama yang lebih tepat
Matt Zimmerman
Saya pikir konsep kedua yang dijelaskan di sini secara teknis disebut Argumen Kata Kunci Sewenang-wenang.
Anshul Dahiya
188

Ada satu fitur bahasa terakhir di mana perbedaannya penting. Pertimbangkan fungsi berikut:

def foo(*positional, **keywords):
    print "Positional:", positional
    print "Keywords:", keywords

The *positionalArgumen akan menyimpan semua argumen posisi dilewatkan ke foo(), dengan tidak ada batas untuk berapa banyak Anda dapat memberikan.

>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}

The **keywordsArgumen akan menyimpan argumen kata kunci:

>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}

Dan tentu saja, Anda dapat menggunakan keduanya sekaligus:

>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}

Fitur-fitur ini jarang digunakan, tetapi kadang-kadang mereka sangat berguna, dan penting untuk mengetahui argumen mana yang posisional atau kata kunci.

terlalu banyak php
sumber
3
Jawaban yang sangat bagus! Hanya sebuah catatan yang memerlukan argumen posisi yang dapat diteruskan sebelum *positionaldan **keywordsjika kita mengubah definisi fungsi seperti def foo(arg1, *positional, **keywords):. Ini arg1posisi dan wajib. Harap dicatat bahwa posisi dalam jawaban berarti jumlah opsional dan variabel argumen posisi.
shaffooo
2
Ya, jawaban yang bagus. Catatan lain: Jika Anda memanggil fungsi foo(bar=True)Anda, Anda bisa mendapatkan nilai yang bar = keywords.pop('bar')sama dengan bar = keywords.pop('bar', None). Untuk nilai default, gunakanbar = keywords.pop('bar', False)
olibre
111

Menggunakan argumen kata kunci sama dengan argumen normal kecuali pesanan tidak masalah. Misalnya, dua fungsi panggilan di bawah ini sama:

def foo(bar, baz):
    pass

foo(1, 2)
foo(baz=2, bar=1)
Eli Gray
sumber
3
Terima kasih untuk ini. Ini sangat berguna yang saya dapat baik menentukan kata kunci arg sebagai arg posisional, dan arg posisi sebagai kata kunci arg.
Luke Davis
47

Argumen Posisi

Mereka tidak memiliki kata kunci sebelum mereka. Urutan itu penting!

func(1,2,3, "foo")

Argumen Kata Kunci

Mereka memiliki kata kunci di bagian depan. Mereka bisa dalam urutan apa pun!

func(foo="bar", baz=5, hello=123)

func(baz=5, foo="bar", hello=123)

Anda juga harus tahu bahwa jika Anda menggunakan argumen default dan lalai untuk memasukkan kata kunci, maka urutannya akan penting!

def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
Tidak dikenal
sumber
8
IMHO, contoh ke-3 (argumen default) tidak jelas. Saya pikir Anda berbicara tentang apa yang terjadi ketika satu atau lebih parameter menyatakan nilai default, dan panggilan menggunakan notasi posisi, tetapi memasok KURANG dari jumlah parameter yang dinyatakan. Namun, contoh Anda memiliki 3 deklarasi, dan 3 dalam panggilan, sehingga nilai default tidak berpengaruh sama sekali! Apakah Anda bermaksud menghilangkan argumen ke-3. misalnya func("bar", 5)? Dan kemudian katakan bahwa hellomendapatkan nilai default 3.
ToolmakerSteve
25

Ada dua cara untuk menetapkan nilai argumen ke parameter fungsi, keduanya digunakan.

  1. Menurut Posisi. Argumen posisi tidak memiliki kata kunci dan ditetapkan terlebih dahulu.

  2. Dengan kata kunci Argumen kata kunci memiliki kata kunci dan diberikan kedua, setelah argumen posisi.

Perhatikan bahwa Anda memiliki opsi untuk menggunakan argumen posisi.

Jika Anda tidak menggunakan argumen posisi, maka - ya - semua yang Anda tulis ternyata menjadi argumen kata kunci.

Ketika Anda memanggil suatu fungsi Anda membuat keputusan untuk menggunakan posisi atau kata kunci atau campuran. Anda dapat memilih untuk melakukan semua kata kunci jika Anda mau. Sebagian dari kita tidak membuat pilihan ini dan menggunakan argumen posisi.

S.Lott
sumber
1
Ohh, saya berpikir bahwa parameter, ketika apa yang sebenarnya adalah argumen (apa yang saya berikan). Terima kasih!
mk12
24

Saya terkejut bahwa tidak ada yang menunjukkan bahwa seseorang dapat melewati kamus parameter argumen kunci, yang memenuhi parameter formal, seperti itu.

>>> def func(a='a', b='b', c='c', **kwargs):
...    print 'a:%s, b:%s, c:%s' % (a, b, c)
... 
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>> 
sherman
sumber
11
+1 untuk teknik yang bermanfaat. Maksud Anda akan lebih jelas, tanpa , **kwargs. Itu akan menunjukkan bahwa bahkan fungsi sederhana, dengan parameter yang pasti, dapat disediakan kamus. Artinya, tidak memerlukan sesuatu yang mewah dalam definisi. MAKA Anda dapat menambahkan contoh kedua, DENGAN ** kwargs dalam definisi, dan menunjukkan bagaimana item EXTRA dalam kamus tersedia melalui itu.
ToolmakerSteve
1
Saya telah melihat ini terjadi di berbagai kode sumber perpustakaan dan sangat bingung. Terima kasih sudah membereskannya!
Craig Labenz
3
Parameter formal keempat di atas - ** kwarg diperlukan jika Anda pernah memanggil func dengan kamus yang berisi kunci selain 'a', 'b' dan 'c'.
Eduardo
Bagi saya print 'a:%s, b:%s, c:%s' % (a, b, c)memberikan kesalahan sintaks, namun print('a:%s, b:%s, c:%s' % (a, b, c))berhasil. Sesuatu dengan versi Python? Pokoknya terima kasih atas wawasan ini, sampai sekarang saya menggunakan yang lebih kikukprint('a:{}, b:{}, c:{}'.format(a, b, c))
Axel Bregnsbo
17

Menggunakan Python 3 Anda dapat memiliki baik kata kunci yang dibutuhkan dan tidak dibutuhkan argumen :


Opsional : (nilai default ditentukan untuk param 'b')

def func1(a, *, b=42):
    ...
func1(value_for_a) # b is optional and will default to 42

Wajib (tidak ada nilai default yang ditentukan untuk param 'b'):

def func2(a, *, b):
    ... 
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`

Ini dapat membantu dalam kasus di mana Anda memiliki banyak argumen serupa di samping satu sama lain terutama jika mereka dari jenis yang sama, dalam hal itu saya lebih suka menggunakan argumen bernama atau saya membuat kelas khusus jika argumen milik bersama.

Christophe Roussy
sumber
3
The diperlukan varian ini cukup berguna. Ini mendesak untuk memberikan arg dengan nama tanpa memberikan default, yang sering tidak masuk akal.
TNT
Nilai default terlihat bagus dan dapat membantu Anda menghemat waktu saat Anda memulai, tetapi pada akhirnya nilai default bisa menjadi PITA.
Christophe Roussy
11

Saya terkejut tidak ada yang menyebutkan fakta bahwa Anda dapat menggabungkan argumen posisi dan kata kunci untuk melakukan hal-hal licik seperti ini menggunakan *argsdan **kwargs( dari situs ini ):

def test_var_kwargs(farg, **kwargs):
    print "formal arg:", farg
    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

Ini memungkinkan Anda untuk menggunakan argumen kata kunci sewenang-wenang yang mungkin memiliki kunci yang tidak ingin Anda tentukan di muka.

Gabriel Hurley
sumber
0

Saya sedang mencari contoh yang memiliki kwarg default menggunakan anotasi tipe:

def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
     return ' '.join([a, b, c, str(kwargs)])

contoh:

>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}
jmunsch
sumber
0

Cukup tambahkan / tambahkan cara untuk mendefinisikan nilai default argumen yang tidak ditetapkan dalam kata-kata kunci saat memanggil fungsi:

def func(**keywargs):
if 'my_word' not in keywargs:
    word = 'default_msg'
else:
    word = keywargs['my_word']
return word

sebut ini dengan:

print(func())
print(func(my_word='love'))

Anda akan mendapatkan:

default_msg
love

baca lebih lanjut tentang *argsdan **kwargsdengan python: https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

sonictl
sumber