args ve **kwargs kullanımı

Bu yüzden *args ve **kwargs kavramlarıyla ilgili zorluk yaşıyorum.

Şimdiye kadar bunu öğrendim:

  • *args = argümanların listesi - konumsal argümanlar olarak
  • **kwargs = sözlük - anahtarları ayrı anahtar kelime argümanları ve değerleri bu argümanların değerleri haline gelir.

Bunun hangi programlama görevi için yararlı olacağını anlamıyorum.

Olabilir:

Listeleri ve sözlükleri bir işlevin bağımsız değişkenleri olarak VE aynı zamanda bir joker karakter olarak girmeyi düşünüyorum, böylece HERHANGİ bir bağımsız değişken geçebilir miyim?

*argsve**kwargs`ın nasıl kullanıldığını açıklayan basit bir örnek var mı?

Ayrıca bulduğum eğitimde sadece "*" ve bir değişken adı kullanılmış.

*argsve*kwargssadece yer tutucular mı yoksa kodda tam olarakargsve**kwargs` mı kullanıyorsunuz?

Çözüm

Sözdizimi * ve ** şeklindedir. *argsve**kwargs` adları yalnızca gelenekseldir, ancak bunları kullanmak için zor bir gereklilik yoktur.

Fonksiyonunuza kaç tane argüman aktarılacağından emin olmadığınızda *args kullanırsınız, yani fonksiyonunuza rastgele sayıda argüman aktarmanıza izin verir. Örneğin:

>>> 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

Benzer şekilde, **kwargs önceden tanımlamadığınız adlandırılmış argümanları ele almanızı sağlar:

>>> 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

Bunları adlandırılmış argümanlarla birlikte de kullanabilirsiniz. Açık argümanlar önce değer alır ve sonra diğer her şey *args ve **kwargs'a aktarılır. Adlandırılmış argümanlar listede ilk sırada gelir. Örneğin:

def table_things(titlestring, **kwargs)

Her ikisini de aynı işlev tanımında kullanabilirsiniz, ancak *args **kwargsdan önce gelmelidir.

Bir fonksiyonu çağırırken * ve ** sözdizimini de kullanabilirsiniz. Örneğin:

>>> 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

Bu durumda görebileceğiniz gibi, öğelerin listesini (veya tuple'ını) alır ve paketinden çıkarır. Bu sayede onları işlevdeki argümanlarla eşleştirir. Elbette, hem fonksiyon tanımında hem de fonksiyon çağrısında bir * olabilir.

Yorumlar (7)

*argsve**kwargs` kullanımının oldukça faydalı olduğu yerlerden biri de alt sınıflamadır.

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)

Bu şekilde, Foo hakkında çok fazla bilgi sahibi olmak zorunda kalmadan Foo sınıfının davranışını genişletebilirsiniz. Değişebilecek bir API için programlama yapıyorsanız bu oldukça kullanışlı olabilir. MyFoo sadece tüm argümanları Foo sınıfına aktarır.

Yorumlar (8)

*argsvekwargsveyakw` adları tamamen gelenekseldir. Birbirimizin kodunu okumamızı kolaylaştırır

Kullanışlı olduğu yerlerden biri struct modülünü kullanırken

struct.unpack()bir tuple döndürürken,struct.pack()değişken sayıda argüman kullanır. Verileri işlerkenstruck.pack()` fonksiyonuna bir tuple aktarabilmek kullanışlıdır, örn.

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

bu yetenek olmadan yazmak zorunda kalırdınız

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

Bu da format_str değişirse ve tuple'ın boyutu değişirse, geri dönüp o gerçekten uzun satırı düzenlemem gerektiği anlamına gelir

Yorumlar (0)