Apa nama ** dalam python?

59

Saat memprogram Python saya terkadang melakukan a **untuk melakukan konversi. Saya mengerti apa yang dilakukannya tetapi struktur data apa yang saya manipulasi? A dictdan apa yang lainnya? Sebuah array? Apakah ada nama untuk **operator?

Niklas Rosencrantz
sumber
3
operator eksponensial?
Benteng
12
Ada dua arti untuk **. Kekuatan dan "kamus argumen kata kunci". Apa yang kamu bicarakan? Dokumentasi memiliki kata-kata ini: "Jika bentuk" ** pengenal "ada, ini diinisialisasi ke kamus baru yang menerima argumen kata kunci berlebih, default ke kamus kosong baru." Mana di antara mereka yang tampaknya relevan dengan pertanyaan Anda?
S.Lott
"Kamus argumen kata kunci" adalah yang saya tanyakan. Terima kasih atas komentarnya.
Niklas Rosencrantz

Jawaban:

86

Ini bukan operator, jadi tidak benar - benar memiliki nama, tetapi didefinisikan sebagai "aturan sintaksis" . Jadi itu harus disebut:

  • "argumen kata kunci membongkar sintaks"

Jika Anda memiliki daftar argumen,, *argsitu disebut "argument unpacking" , dengan cara yang sama **kwargsdisebut "argumen argumen unpacking" .

Jika Anda menggunakannya di sisi kiri =, seperti pada a, *middle, end = my_tuple, Anda akan mengatakan "tuple unpacking" .

Secara total, ada tiga jenis argumen (parameter tunggal):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

The *argsargumen disebut "variabel posisi parameter" dan **kwargsadalah "parameter kunci variabel". Argumen khusus kata kunci tidak dapat diberikan secara posisi, karena parameter posisi variabel akan mengambil semua argumen yang Anda berikan.

Sebagian besar ini dapat ditemukan di PEPs 0362 dan 3102 , serta di bagian Aliran Kontrol dokumen. Perlu dicatat bahwa objek tanda tangan fungsi PEP hanya konsep, dan terminologi mungkin hanya ide satu orang. Tapi toh itu istilah yang bagus. :)

Jadi argumen *dan **hanya membongkar struktur data masing-masing:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables adalah objek yang mengimplementasikan __iter__()metode dan pemetaan adalah objek yang mengimplementasikan keys()dan __getitem__(). Setiap objek yang mendukung protokol ini akan dipahami oleh konstruktor tuple()dan dict(), sehingga mereka dapat digunakan untuk membongkar argumen.

Stefano Palazzo
sumber
3
Seandainya ada orang yang bingung, def f(x, *xs, y=0): passsintaks Python 2. {5,6,7} tidak valid, juga tidak def f(x, y=0, *xs):melakukan apa yang Anda harapkan. AFAIK, satu-satunya cara untuk mencapai efek (yang jelas) yang dimaksud adalah def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 menangani sintaks asli seperti yang diharapkan.
chbrown
1
Sementara kami melakukannya: begin, *middle, end = (0, 1, 2, 3, 4, 5)sintaksnya juga tidak berfungsi di Python 2.x.
Stefano Palazzo
Jawaban ini salah dalam Python 3.5 dan yang lebih baru. PEP-448 menetapkan operator ** sebagai operator pembongkar kamus. Lihat python.org/dev/peps/pep-0448
devnul3
13

Saya tidak berpikir itu memiliki nama. Dalam Python Docs di bawah "Unpacking Argument Lists", itu hanya disebut sebagai " **-operator."

Saya tidak yakin apa yang Anda maksud dengan struktur data "yang lain". Ketika Anda melakukannya, f(**kwargs)Anda membongkar kamus kwargssebagai urutan pasangan kunci-nilai. Saya tidak melihat ada struktur lain yang terlibat.

Saya akan menyalin contoh dalam dokumentasi di atas untuk kejelasan.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Lihat juga: Apa arti * args dan ** kwargs?

Kris Harper
sumber
Ada beberapa cara yang mungkin dilakukan pembaca untuk menafsirkan f(**kwargs)...
Deer Hunter
3

Jika Anda tidak yakin apa yang harus memanggil operator tertentu atau jika tidak disebutkan namanya, Anda selalu dapat menggunakan Waka Waka Bang Splat sebagai referensi untuk membantu Anda mencari tahu apa yang memanggilnya. Dalam hal ini **saya akan menyebutnya double-splat, meskipun ada beberapa nama alternatif untuk simbol .

aculich
sumber