İşlev bağımsız değişkenlerinde yıldız işareti var mı?


242

Bir fonksiyonun argümanlarındaki çıplak yıldız işareti ne işe yarar?

Turşu modülüne baktığımda şunu görüyorum:

pickle.dump(obj, file, protocol=None, *, fix_imports=True)

(Değişken bağımsız değişken sayısı için) bağımsız değişkenlerden önce tek ve çift yıldız hakkında biliyorum, ama bu hiçbir şeyden önce. Ve bunun turşu ile ilgisi olmadığından eminim. Bu muhtemelen bunun bir örneği. Adını sadece bunu tercümana gönderdiğimde öğrendim:

>>> def func(*):
...     pass
...
  File "<stdin>", line 1
SyntaxError: named arguments must follow bare *

Önemli ise, python 3.3.0 kullanıyorum.


Yanıtlar:


221

Bare *, arayanı adlandırılmış argümanlar kullanmaya zorlamak için kullanılır. Bu nedenle, *aşağıdaki anahtar kelime bağımsız değişkenleriniz olmadığında bir işlevi bağımsız değişken olarak tanımlayamazsınız .

Daha fazla ayrıntı için bu cevaba veya Python 3 belgelerine bakın.


3
Tüm konumsal (adsız) argümanların *argsçıplak önce gerçekleşmesi gerektiğini unutmayın *.
BallpointBen

4
Ayrıca, yalnızca konum bağımsız değişkenlerinin sonunu işaret eden bir tür karşı öğe olduğunu unutmayın ( stackoverflow.com/questions/28243832/… ).
Stephen

2
@BallpointBen: *yerine *argsveya tam tersi; imzada bir arada var olamazlar. Bu yüzden seçtiler *; Daha önce, *argstamamen pozisyonel argümanları zorlamak için tek yol olduğunu ve bu tartışmaların sona erdi olabilir (kalan tüm konumsal argümanları toplanan beri, bunlar aşağıdaki adlı argümanları ulaşabilir) pozisyonel olarak geçilecek. *aynı "konumsal argümanlar buradan öteye geçemez" anlamına gelir, ama bir adın olmaması "ama onları kabul etmeyeceğim, çünkü onları koyacak bir yer vermemeyi seçtim".
ShadowRanger

70

Orijinal cevap soruyu tamamen cevaplasa da, biraz ilgili bilgiler ekleyerek. Tek yıldız işareti davranışı türetilmiştir PEP-3102. İlgili bölümden alıntı:

The second syntactical change is to allow the argument name to
be omitted for a varargs argument. The meaning of this is to
allow for keyword-only arguments for functions that would not
otherwise take a varargs argument:

    def compare(a, b, *, key=None):
        ...

Basit İngilizce'de, anahtarın değerini geçmek için, açıkça olarak geçmeniz gerektiği anlamına gelir key="value".


Oh, bu işleri daha açık hale getiriyor. Yani aslında * argümanına sahip olmak tıpkı argümanlara * sahip olmak gibidir, ancak herhangi bir isim vermedikçe, tek etkisi muhtemelen kalan argümanları anahtar kelime olmaya zorlamak için geri kalan tüm konumsal argümanları sessizce silip süpürmektir. -sadece.
Stephen

11
@Stephen Ben de aslında, çıplak etkisi *kalan konumsal argümanları silip süpürmek olduğunu düşündüm , ama durum böyle değil. İşlev beklediğinden daha fazla konumsal argüman iletmek, bu tür bir hata verir:foo() takes exactly 1 positional argument (2 given)
Ajay M

19
def func(*, a, b):
    print(a)
    print(b)

func("gg") # TypeError: func() takes 0 positional arguments but 1 was given
func(a="gg") # TypeError: func() missing 1 required keyword-only argument: 'b'
func(a="aa", b="bb", c="cc") # TypeError: func() got an unexpected keyword argument 'c'
func(a="aa", b="bb", "cc") # SyntaxError: positional argument follows keyword argument
func(a="aa", b="bb") # aa, bb

** kwargs ile yukarıdaki örnek

def func(*, a, b, **kwargs):
    print(a)
    print(b)
    print(kwargs)

func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}

6

Anlamsal olarak, izleyen bağımsız değişkenlerin yalnızca anahtar kelime olduğu anlamına gelir, bu nedenle adını belirtmeden bir bağımsız değişken sağlamaya çalışırsanız bir hata alırsınız. Örneğin:

>>> def f(a, *, b):
...     return a + b
...
>>> f(1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 1 positional argument but 2 were given
>>> f(1, b=2)
3

Pragmatik olarak, bu işlevi bir anahtar kelime argümanıyla çağırmanız gerektiği anlamına gelir. Genellikle, argümanın adının verdiği ipucu olmadan argümanın amacını anlamak zor olduğunda yapılır.

Örneğin sorted(nums, reverse=True)yazdıysanız vs. ile karşılaştırın sorted(nums, True). İkincisi çok daha az okunabilir olacaktır, bu nedenle Python geliştiricileri onu daha önce yazmanızı seçti.


4

Diyelim ki fonksiyonunuz var:

def sum(a,key=5):
    return a + key 

Bu işlevi 2 şekilde çağırabilirsiniz:

sum(1,2) veya sum(1,key=2)

İşlevin sumyalnızca anahtar kelime bağımsız değişkenleri kullanılarak çağrılmasını istediğinizi varsayalım .

*Konumsal bağımsız değişkenlerin sonunu işaretlemek için işlev parametre listesine eklersiniz .

Yani fonksiyon şöyle tanımlanır:

def sum(a,*,key=5):
    return a + key 

sadece kullanılarak çağrılabilir sum(1,key=2)


-1

Çok açıklayan yardımcı olmak için aşağıdaki linki buldum *, *argsve **kwargs:

https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/

Esasen, yukarıdaki cevaplara ek olarak, yukarıdaki siteden öğrendim (kredi: https://pythontips.com/author/yasoob008/ ):

Aşağıda ilk olarak gösterim işlevi ile, biri diğeri de olmak üzere iki örnek *argsvardır.**kwargs

def test_args_kwargs(arg1, arg2, arg3):
    print "arg1:", arg1
    print "arg2:", arg2
    print "arg3:", arg3

# first with *args
>>> args = ("two", 3,5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5

# now with **kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two","arg1":5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3

Böylece *argsdinamik olarak beslendikleri sırayla alınacak argümanların bir listesini oluşturmanıza izin verirken **kwargs, NAMED argümanlarının iletilmesini etkinleştirebilir ve NAME tarafından buna göre (beslendikleri sıraya bakılmaksızın) işlenebilir .

Site, argümanların doğru sıralanmasının olması gerektiğini belirterek devam ediyor:

some_func(fargs,*args,**kwargs)

2
Bu cevabın soru ile hemen hemen hiçbir ilgisi yoktur. Hatta özelliği olmayan eski bir python sürümü kullanıyor.
Antti Haapala
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.