** kwargs argümanını ** kwargs ile başka bir işleve geçirme


152

Aşağıdaki örneği anlamıyorum, diyelim ki bu işlevlere sahibim:

# python likes
def save(filename, data, **kwargs):
    fo = openX(filename, "w", **kwargs) # <- #1
    fo.write(data)
    fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
    fo = openX(filename, "w", kwargs) # <- #2
    fo.write(data)
    fo.close()

def openX(filename, mode, **kwargs):
    #doing something fancy and returning a file object

# 1 neden doğru çözüm ve # 2 yanlış çözüm? **kwargstemelde bir diksiyon, bu yüzden openX konusundaki argümanı aktarmak istersem, doğru yolun söz konusu olmadan **ve sadece doğru yol olacağını düşünüyorum . Ama python açıkça ikincisini sevmiyor ve bana 2 argüman yerine 3 verdiğimi söylüyor. Peki bunun sebebi ne?

python 

5
Neden **argskodda çağırdığını merak ediyorum . İnsanların kafasını karıştıracağı için bu muhtemelen en kötü isim*args
John La Rooy

1
Asla gerçekten * args kullanmıyorum, bu yüzden ** args ^^ kullanıyorum, ama onu değiştirebilirim.

Yanıtlar:


155

İkinci örnekte 3 argüman sağlarsınız: dosya adı, mod ve sözlük ( kwargs). Ancak Python şunları bekliyor: 2 resmi argüman artı anahtar kelime argümanları.

Sözlüğü '**' ön ekiyle, sözlüğü kwargsanahtar kelimeler argümanlarına açarsınız.

Sözlük (tür dict), anahtar / değer çiftlerini içeren tek bir değişkendir.

"Anahtar kelime bağımsız değişkenleri" anahtar / değer yöntemi parametreleridir.

Herhangi bir sözlük, **işlev çağrısı sırasında önüne ekleyerek anahtar kelime bağımsız değişkenlerine paketten çıkarılabilir .


5
şimdi anladım. Anahtar kelimeler ve diksiyonların aynı şey olduğunu düşündüm.

13
"Herhangi bir sözlük, işlev çağrısı sırasında ** ile önek olarak anahtar kelimelere genişletilebilir." <- thats cool


8
Gerçek bir kod örneği bu cevabı oldukça açık hale getirecektir.
OrangeDog

13

**Sözdizimi sözlüğüne toplamak anahtar kelime argümanları Python söyler. Bu save2anahtar kelimeyi anahtar kelime olmayan bir bağımsız değişken (sözlük nesnesi) olarak geçiriyor. openXBöylece herhangi bir anahtar kelime argümanları göremiyorsa **argsalışması etmez. Bunun yerine üçüncü bir anahtar kelime olmayan bağımsız değişken (sözlük) alıyor. Bunu düzeltmek için openXişlevin tanımını değiştirin .

def openX(filename, mode, kwargs):
    pass

Teşekkür ederim, ama ben de kaydetmeden openX kullanmak istiyorum, bu yüzden anahtar kelimeler ile sopa zorunda. Anahtar kelimeleri

@xMRW Bir sözlüğü herhangi bir işleve parametre olarak geçirebileceğiniz için aynı şey olamazlar. O zaman # 1'iniz doğru.
Keith

8

@Gecco'nun cevabını genişleterek, size farkı gösterecek bir örnek aşağıdadır:

def foo(**kwargs):
    for entry in kwargs.items():
        print("Key: {}, value: {}".format(entry[0], entry[1]))

# call using normal keys:
foo(a=1, b=2, c=3)
# call using an unpacked dictionary:
foo(**{"a": 1, "b":2, "c":3})

# call using a dictionary fails because the function will think you are
# giving it a positional argument
foo({"a": 1, "b": 2, "c": 3})
# this yields the same error as any other positional argument
foo(3)
foo("string")

Burada bir sözlüğü açmanın nasıl çalıştığını ve gerçek bir sözlük göndermenin neden başarısız olduğunu görebilirsiniz


1

Çünkü sözlük tek bir değerdir. Bir anahtar kelime bağımsız değişkenleri grubu olarak iletmek istiyorsanız anahtar kelime genişlemesini kullanmanız gerekir.


üzgünüm, ancak "anahtar kelime genişletmesi" nedir? yani ** argümanlar yerine dict_var kullanmalıyım ve sadece def func (argüman, dict_var = 0) ... func (1, {1: "a", 2: "b"}) kullanmalıyım

1

# 2 için argümanlar sadece dikte değerine sahip resmi bir parametre olacak, ancak bir anahtar kelime tipi parametresi olmayacaktır.

Bir anahtar kelime türü parametresini bir anahtar kelime bağımsız değişkenine geçirmek istiyorsanız Sözlüğünüzden önce belirli ** ifadesini kullanmanız gerekir, yani ** argümanlar

** kw kullanımı hakkında daha fazla bilgi için buna göz atın

http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/


Yani ** kwargs ve dict arasında büyük bir fark var mı?

teşekkür ederim, her zaman anlamadığım konular hakkında daha fazla okumak isterim.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.