Penggunaan *args dan **kwargs

Sehingga saya mengalami kesulitan dengan konsep *args dan **kwargs.

Sejauh ini saya telah belajar bahwa:

  • *args = daftar argumen - sebagai argumen posisi
  • **kwargs = dictionary - dan tombol menjadi terpisah kata kunci argumen dan nilai-nilai yang menjadi nilai-nilai dari argumen ini.

Saya don't memahami apa tugas pemrograman ini akan bermanfaat untuk.

Mungkin:

Saya pikir untuk memasukkan daftar kamus sebagai argumen dari fungsi DAN pada saat yang sama sebagai wildcard, sehingga aku dapat melewati SETIAP argumen?

Ini ada contoh sederhana untuk menjelaskan bagaimana *args dan **kwargs yang digunakan?

Juga tutorial yang saya temukan digunakan hanya "*" dan nama variabel.

Ini adalah *args dan **kwargs hanya penampung atau apakah yang anda gunakan benar-benar *args dan **kwargs dalam kode?

Mengomentari pertanyaan (6)
Larutan

Sintaks adalah * dan **. Nama-nama *args dan **kwargs hanya dengan konvensi tapi ada's tidak ada kebutuhan untuk menggunakannya.

Anda akan menggunakan *args ketika anda're tidak yakin berapa banyak argumen yang mungkin akan dilewatkan ke fungsi, yaitu hal ini memungkinkan anda melewati jumlah yang sewenang-wenang argumen untuk fungsi anda. Misalnya:

>>> def print_everything(*args):
        for count, thing in enumerate(args):
...         print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage

Demikian pula, **kwargs memungkinkan anda untuk menangani bernama argumen yang anda miliki tidak didefinisikan terlebih dahulu:

>>> def table_things(**kwargs):
...     for name, value in kwargs.items():
...         print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit

Anda dapat menggunakan ini bersama dengan argumen bernama terlalu. Eksplisit argumen mendapatkan nilai pertama dan kemudian segala sesuatu yang lain akan diteruskan ke *args dan **kwargs. Bernama argumen datang pertama dalam daftar. Misalnya:

def table_things(titlestring, **kwargs)

Anda juga dapat menggunakan baik dalam fungsi yang sama tapi definisi *args harus terjadi sebelum **kwargs.

Anda juga dapat menggunakan * dan ** sintaks ketika memanggil sebuah fungsi. Misalnya:

>>> def print_three_things(a, b, c):
...     print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat

Seperti yang anda lihat dalam hal ini dibutuhkan daftar (atau tupel) dari barang dan menafsirkannya. Dengan ini pertandingan mereka untuk argumen fungsi. Tentu saja, anda bisa memiliki * kedua dalam definisi fungsi dan pada pemanggilan fungsi.

Komentar (7)

Salah satu tempat di mana penggunaan *args dan **kwargs yang cukup berguna adalah untuk subclassing.

class Foo(object):
    def __init__(self, value1, value2):
        # do something with the values
        print value1, value2

class MyFoo(Foo):
    def __init__(self, *args, **kwargs):
        # do something else, don't care about the args
        print 'myfoo'
        super(MyFoo, self).__init__(*args, **kwargs)

Dengan cara ini anda dapat memperpanjang perilaku Foo kelas, tanpa harus tahu terlalu banyak tentang Foo. Hal ini dapat cukup nyaman jika anda membuat program untuk sebuah API yang bisa berubah. MyFoo hanya melewati semua argumen ke Foo kelas.

Komentar (8)

Berikut ini's contoh yang menggunakan 3 jenis parameter.

def func(required_arg, *args, **kwargs):
    # required_arg is a positional-only parameter.
    print required_arg

    # args is a tuple of positional arguments,
    # because the parameter name has * prepended.
    if args: # If args is not empty.
        print args

    # kwargs is a dictionary of keyword arguments,
    # because the parameter name has ** prepended.
    if kwargs: # If kwargs is not empty.
        print kwargs

>>> func()
Traceback (most recent call last):
  File "", line 1, in 
TypeError: func() takes at least 1 argument (0 given)

>>> func("required argument")
required argument

>>> func("required argument", 1, 2, '3')
required argument
(1, 2, '3')

>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
required argument
(1, 2, '3')
{'keyword2': 'foo', 'keyword1': 4}
Komentar (0)

Berikut ini's salah satu tempat favorit saya untuk menggunakan ** sintaks seperti di Dave Webb's akhir contoh:

mynum = 1000
mystr = 'Hello World!'
print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals())

I'm tidak yakin jika ini's sangat cepat bila dibandingkan dengan hanya menggunakan nama mereka sendiri, tetapi itu's jauh lebih mudah untuk mengetik!

Komentar (8)

Salah satu kasus di mana *args dan **kwargs berguna adalah ketika menulis fungsi pembungkus (seperti dekorator) yang perlu untuk dapat menerima sewenang-wenang argumen untuk melewati ke fungsi yang dibungkus. Misalnya, sederhana dekorator yang mencetak argumen dan mengembalikan nilai dari fungsi yang dibungkus:

def mydecorator( f ):
   @functools.wraps( f )
   def wrapper( *args, **kwargs ):
      print "Calling f", args, kwargs
      v = f( *args, **kwargs )
      print "f returned", v
      return v
   return wrapper
Komentar (0)

*args dan **kwargs khusus-magic fitur Python. Berpikir tentang fungsi yang bisa memiliki jumlah yang tidak diketahui dari argumen. Misalnya, untuk alasan apapun, anda ingin memiliki fungsi yang jumlah tidak diketahui jumlah angka (dan anda don't ingin menggunakan built-in fungsi sum). Jadi anda menulis fungsi ini:

def sumFunction(*args):
  result = 0
  for x in args:
    result += x
  return result

dan menggunakannya seperti: sumFunction(3,4,6,3,6,8,9).

kwargs memiliki fungsi yang berbeda. Dengan kwargs anda dapat memberikan sewenang-wenang kata kunci argumen ke fungsi tersebut dan anda dapat mengaksesnya sebagai dictonary.

def someFunction(**kwargs):
  if 'text' in kwargs:
    print kwargs['text']

Panggilan someFunction(teks="anu") akan mencetak foo.

Komentar (0)

Bayangkan anda memiliki sebuah fungsi tetapi anda don't ingin membatasi jumlah parameter yang dibutuhkan. Contoh:

>>> import operator
>>> def multiply(*args):
...  return reduce(operator.mul, args)

Kemudian anda menggunakan fungsi ini seperti:

>>> multiply(1,2,3)
6

or

>>> numbers = [1,2,3]
>>> multiply(*numbers)
6
Komentar (0)

Nama-nama *args dan **kwargs atau **kw adalah murni oleh konvensi. Itu membuat lebih mudah bagi kita untuk membaca satu sama lain's kode

Salah satu tempat hal ini berguna ketika menggunakan struct modul

struct.membongkar() mengembalikan sebuah tuple sedangkan struct.pack() menggunakan variabel jumlah argumen. Ketika memanipulasi data akan lebih mudah untuk dapat melewati sebuah tuple untuk memukul.pack() misalnya.

tuple_of_data = struct.unpack(format_str, data)
... manipulate the data
new_data = struct.pack(format_str, *tuple_of_data)

tanpa kemampuan ini anda akan dipaksa untuk menulis

new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)

yang juga berarti jika format_str perubahan dan ukuran tupel perubahan, saya'll harus kembali dan mengedit yang benar-benar panjang garis

Komentar (0)

Perhatikan bahwa *args/*kwargs merupakan bagian dari fungsi-panggilan sintaks, dan tidak benar-benar seorang operator. Ini memiliki efek samping tertentu yang aku berlari ke dalam, yang adalah bahwa anda dapat't digunakan args ekspansi dengan pernyataan print, sejak print bukan fungsi.

Hal ini tampaknya masuk akal:

def myprint(*args):
    print *args

Sayangnya itu doesn't mengkompilasi (syntax error).

Ini mengkompilasi:

def myprint(*args):
    print args

Tapi mencetak argumen sebagai tuple, yang isn't apa yang kita inginkan.

Ini adalah solusi aku menetap pada:

def myprint(*args):
    for arg in args:
        print arg,
    print
Komentar (2)

Parameter ini biasanya digunakan untuk fungsi proxy, jadi proxy dapat melewati setiap parameter input untuk fungsi target.

def foo(bar=2, baz=5):
    print bar, baz

def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments
    print x
    foo(*args, **kwargs) # applies the "non-x" parameter to foo

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

Tapi karena parameter ini menyembunyikan parameter sebenarnya nama-nama itu, lebih baik untuk menghindari mereka.

Komentar (0)

Anda bisa melihat-lihat di python docs (docs.python.org di FAQ), tetapi lebih khusus untuk penjelasan yang baik misterius miss args dan mister kwargs (courtesy of archive.org) (asli, mati link ini di sini).

Singkatnya, baik digunakan ketika parameter opsional untuk fungsi atau metode yang digunakan. Sebagai Dave mengatakan, *args digunakan ketika anda don't tahu berapa banyak argumen dapat diteruskan, dan **kwargs ketika anda ingin menangani parameter yang ditentukan oleh nama dan nilai seperti dalam:

myfunction(myarg=1)
Komentar (2)