Bir işleve isteğe bağlı parametreleri aktarmanın bir yolu var mı?


133

Python'da bir işlevi çağırırken isteğe bağlı parametreleri bir işleve geçirmenin bir yolu var mı ve işlev tanımında "yalnızca isteğe bağlı parametre geçirilirse" temelli bir kod var mı?

Yanıtlar:


115

Python 2 belgeler, 7.6. Fonksiyon tanımları , arayan kişinin isteğe bağlı bir parametre verip vermediğini algılamanın birkaç yolunu sunar.

İlk olarak, özel biçimsel parametre sözdizimi kullanabilirsiniz *. İşlev tanımının önünde tek bir biçimsel parametre varsa, *Python bu parametreyi önceki biçimsel parametrelerle (bir tuple olarak) eşleşmeyen konumsal parametrelerle doldurur. İşlev tanımının önünde biçimsel bir parametre varsa, **Python bu parametreyi önceki biçimsel parametrelerle (bir dikt olarak) eşleşmeyen anahtar sözcük parametreleriyle doldurur. İşlevin uygulaması, bu parametrelerin içeriğini istediğiniz türden "isteğe bağlı parametreler" için kontrol edebilir.

Örneğin, burada opt_funiki konumsal parametre alan x1ve x2"isteğe bağlı" adlı başka bir anahtar kelime parametresi arayan bir işlev var .

>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
...     if ('optional' in keyword_parameters):
...         print 'optional parameter found, it is ', keyword_parameters['optional']
...     else:
...         print 'no optional parameter, sorry'
... 
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is  yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry

İkinci olarak, Nonearayanın asla kullanmayacağı bir değerin varsayılan bir parametre değerini sağlayabilirsiniz . Parametre bu varsayılan değere sahipse, arayanın parametreyi belirtmediğini anlarsınız. Parametrenin varsayılan olmayan bir değeri varsa, arayandan geldiğini bilirsiniz.


7
positional_parametersbir demet ve keyword_parametersbir sözlüktür.
Cees Timmerman

Python formal parameters preceded by * (buna ne denir?) A'dan nasıl ayırt edilir keyword parameter? Anladığım kadarıyla, anahtar kelime parametreleri =, fonksiyon çağrısında operatör kullanılarak belirtilir (bu nedenle opt_fun(1,2, optional="yes"), parametreyi öngören ancak zorunlu olarak gerektirmeyen bir fonksiyon için bir anahtar kelime argümanı "evet" sağlar option).
Minh Tran

Öte yandan, formal parameters preceded by * basitçe "arayan tarafından sağlanan ve herhangi bir anahtar kelime argümanından önce gelen konumsal argümanlara karşılık gelmeyen argümanlar" olarak anladım . Örneğin, opt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018"), "blah"ve 3.14vardır forma arguments preceded by *iki pozisyonel argümanlar ve kullandığı argüman arasına çünkü =işareti. Ortaya çıkan tanımlama grubu positional_parameterikili olacaktır: ("blah", 3.14). Bu doğru mu?
Minh Tran

@MinhTran, yorumlardaki sorular Stack Overflow'da yanıt almanın en iyi yolu değil. Büyük mavi "Soru Sor" düğmesini tıklamak ve isteğinizi başkalarının "Cevaplayabileceği" bir "Soru" olarak yazmak çok daha iyidir. Ama size yardımcı olmak için, a) not parameter" parameters" için " değil" " " yazdım preceded by *. Dil *identifier, parametre listesinde yalnızca birine izin verir . b) docs.python.org/2/reference/…'yi okuyun , c) docs.python.org/2/reference/expressions.html#calls'ı okuyun . Üzgünüz, bu yorumda izin verilen karakter sayısı bitiyor.
Jim DeLaHunt

81
def my_func(mandatory_arg, optional_arg=100):
    print(mandatory_arg, optional_arg)

http://docs.python.org/2/tutorial/controlflow.html#default-argument-values

Bunu kullanmaktan daha okunaklı buluyorum **kwargs.

Bir bağımsız değişkenin aktarılıp aktarılmadığını belirlemek için, varsayılan değer olarak özel bir yardımcı program nesnesi kullanıyorum:

MISSING = object()

def func(arg=MISSING):
    if arg is MISSING:
        ...

-Teşekkürler, bu parametrenin varsayılan değerini kodda başka bir değişken olarak belirtmenin bir yolu var mı?
user1795998

Evet. default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
warvariuc

Bu, isteğe bağlı parametrelerin nasıl kullanılacağını gösterir, ancak birinin geçip geçmediğini nasıl test edeceğini göstermez, ki bu OP'nin sorduğu şeydir.
Mawg, Monica'yı

4
Çoğu durumda bu, Jim'inkinden daha basit ve daha anlaşılır bir çözümdür. Varsayılan değeri Hiçbiri olarak ayarlarsanız, parametrenin geçip geçmediğini kontrol edebilirsiniz. Jim'in çözümünün daha iyi olduğu tek durum, argüman olarak Yok'u geçmek ile bir argümanı hiç iletmemek arasında ayrım yapmanın önemli olmasıdır.
Arnon Axelrod

19
def op(a=4,b=6):
    add = a+b
    print add

i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
 If none or one parameter is passed the default passed parameter will be considered for the function. 

1
İlk parametreyi (a) değil de yalnızca ikinci (b) parametresini geçirmenin bir yolu var mı?
Djidiouf

4
@Djidiouf Evet, varop(b=2)
Jürg Merlin Spaak

7

Bir parametreye varsayılan bir değer vermek isterseniz () 'de değer atayın. (x = 10) gibi. Ancak önemli olan, önce zorunlu argüman, sonra varsayılan değerdir.

Örneğin.

(y, x = 10)

fakat

(x = 10, y) yanlış


Teşekkürler, bu parametrenin varsayılan değerini koddaki başka bir değişken olarak belirtmenin bir yolu var mı?
user1795998

Evet *arg **karg, işlev bağımsız değişkenleri olarak adlandırılan bir şey kullanabilirsiniz . google'da ara.
sumit

Bu, isteğe bağlı parametrelerin nasıl kullanılacağını gösterir, ancak birinin geçip geçmediğini nasıl test edeceğini göstermez, ki bu OP'nin sorduğu şeydir.
Mawg, Monica'yı

2

İşleve asla geçmeyecek bir şeyle isteğe bağlı bağımsız değişken için varsayılan bir değer belirleyebilir ve isoperatörle kontrol edebilirsiniz :

class _NO_DEFAULT:
    def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()

def func(optional= _NO_DEFAULT):
    if optional is _NO_DEFAULT:
        print("the optional argument was not passed")
    else:
        print("the optional argument was:",optional)

o zaman yapmadığınız sürece func(_NO_DEFAULT), argümanın geçip geçmediğini doğru bir şekilde tespit edebilirsiniz ve kabul edilen cevabın aksine ** notasyonun yan etkileri konusunda endişelenmenize gerek yoktur:

# these two work the same as using **
func()
func(optional=1)

# the optional argument can be positional or keyword unlike using **
func(1) 

#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)

Sadece yap _NO_DEFAULT = object().
Aran-Fey

Daha iyi bir iç gözlem için 2 ekstra satır buna değer. Bununla, eğer çalıştırırsanız help(func), açık bir şekilde aktarılmazsa, argümanın nasıl yorumlandığı konusunda daha net bir fikir edinirsiniz.
Tadhg McDonald-Jensen
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.