Gibt es eine Möglichkeit, optionale Parameter an eine Funktion zu übergeben?

132

Gibt es in Python eine Möglichkeit, optionale Parameter während des Aufrufs an eine Funktion zu übergeben und in der Funktionsdefinition einen Code zu haben, der auf "nur wenn der optionale Parameter übergeben wird" basiert?

user1795998
quelle

Antworten:

114

Die Python 2-Dokumentation, 7.6. Mit Funktionsdefinitionen können Sie auf verschiedene Weise feststellen, ob ein Aufrufer einen optionalen Parameter angegeben hat.

Erstens können Sie eine spezielle formale Parametersyntax verwenden *. Wenn der Funktionsdefinition ein formaler Parameter vorangestellt ist *, füllt Python diesen Parameter mit Positionsparametern, die nicht mit vorhergehenden formalen Parametern übereinstimmen (als Tupel). Wenn der Funktionsdefinition ein formaler Parameter vorangestellt ist **, füllt Python diesen Parameter mit Schlüsselwortparametern, die nicht mit vorhergehenden formalen Parametern übereinstimmen (als Diktat). Die Implementierung der Funktion kann den Inhalt dieser Parameter auf beliebige "optionale Parameter" der gewünschten Sortierung überprüfen.

Hier ist zum Beispiel eine Funktion, opt_fundie zwei Positionsparameter x1und verwendet x2und nach einem anderen Schlüsselwortparameter mit dem Namen "optional" sucht.

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

Zweitens können Sie einen Standardparameterwert mit einem Wert angeben, Noneden ein Aufrufer niemals verwenden würde. Wenn der Parameter diesen Standardwert hat, wissen Sie, dass der Aufrufer den Parameter nicht angegeben hat. Wenn der Parameter einen nicht standardmäßigen Wert hat, wissen Sie, dass er vom Aufrufer stammt.

Jim DeLaHunt
quelle
7
positional_parametersist ein Tupel und keyword_parametersein Wörterbuch.
Cees Timmerman
Wie unterscheidet Python formal parameters preceded by * (wie heißt das?) Von a keyword parameter? Nach meinem Verständnis werden Schlüsselwortparameter mithilfe des =Operators im Funktionsaufruf angegeben (daher opt_fun(1,2, optional="yes")wird ein Schlüsselwortargument "yes" für eine Funktion bereitgestellt , die den Parameter antizipiert, aber nicht unbedingt benötigt option).
Minh Tran
Andererseits verstand ich formal parameters preceded by * einfach "die vom Aufrufer bereitgestellten Argumente, die nicht den Positionsargumenten entsprechen, die vor Schlüsselwortargumenten stehen". Zum Beispiel in opt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018"), "blah"und 3.14sind , forma arguments preceded by *weil es zwischen den beiden Positionsargumenten ist und das Argument, das verwendeten =Zeichen. Das resultierende Tupel positional_parameterwäre das Dupel : ("blah", 3.14). Ist das richtig?
Minh Tran
@MinhTran, Fragen in Kommentaren sind nicht der beste Weg, um eine Antwort in Stack Overflow zu erhalten. Es ist weitaus besser, auf die große blaue Schaltfläche "Frage stellen" zu klicken und Ihre Anfrage als "Frage" zu schreiben, die andere "beantworten" können. Aber um Ihnen zu helfen, a) beachten Sie, dass ich " parameter" nicht " parameters" für " preceded by *" geschrieben habe. Die Sprache erlaubt nur einen *identifierin der Parameterliste. b) Lesen Sie docs.python.org/2/reference/… , c) Lesen Sie docs.python.org/2/reference/expressions.html#calls . In diesem Kommentar sind leider keine Zeichen mehr zulässig.
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

Ich finde das lesbarer als zu benutzen **kwargs.

Um festzustellen, ob überhaupt ein Argument übergeben wurde, verwende ich ein benutzerdefiniertes Dienstprogrammobjekt als Standardwert:

MISSING = object()

def func(arg=MISSING):
    if arg is MISSING:
        ...
warvariuc
quelle
- Danke, gibt es eine Möglichkeit, den Standardwert dieses Parameters als eine weitere Variable im Code anzugeben?
user1795998
Ja. default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
Warvariuc
Dies scheint zu zeigen, wie optionale Parameter verwendet werden, aber nicht, wie getestet wird, ob einer übergeben wird, was das OP verlangt.
Mawg sagt, Monica am
4
In den meisten Fällen ist dies die einfachere und direktere Lösung als die von Jim. Wenn Sie den Standardwert auf Keine setzen, können Sie überprüfen, ob der Parameter übergeben wurde oder nicht. Der einzige Fall, in dem Jims Lösung besser ist, ist, wenn es wichtig ist, zwischen dem Übergeben von None als Argument und dem Übergeben von überhaupt keinem Argument zu unterscheiden.
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. 
Sanyal
quelle
1
Gibt es eine Möglichkeit, nur den zweiten Parameter (b) und nicht den ersten (a) zu übergeben?
Djidiouf
4
@ Djidiouf Ja, es gibtop(b=2)
Jürg Merlin Spaak
7

Wenn Sie einem Parameter einen Standardwert geben möchten, weisen Sie in () einen Wert zu. wie (x = 10). Wichtig ist jedoch zuerst das obligatorische Argument und dann der Standardwert.

z.B.

(y, x = 10)

aber

(x = 10, y) ist falsch

sumit
quelle
Gibt es eine Möglichkeit, den Standardwert dieses Parameters als eine weitere Variable im Code anzugeben?
user1795998
Ja, Sie können so etwas *arg **kargwie Funktionsargumente verwenden. googeln.
Summe
Dies scheint zu zeigen, wie optionale Parameter verwendet werden, aber nicht, wie getestet wird, ob einer übergeben wird, was das OP verlangt.
Mawg sagt, Monica am
2

Sie können einen Standardwert für das optionale Argument mit etwas angeben, das niemals an die Funktion übergeben würde, und ihn mit dem isOperator überprüfen :

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)

Solange Sie dies nicht tun func(_NO_DEFAULT), können Sie genau feststellen, ob das Argument übergeben wurde oder nicht, und im Gegensatz zur akzeptierten Antwort müssen Sie sich keine Gedanken über die Nebenwirkungen der ** Notation machen:

# 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)
Tadhg McDonald-Jensen
quelle
Tu es einfach _NO_DEFAULT = object().
Aran-Fey
2 zusätzliche Zeilen für eine bessere Selbstbeobachtung sind es wert. Wenn Sie dies ausführen, erhalten help(func)Sie eine klarere Vorstellung davon, wie das Argument interpretiert wird, wenn es nicht explizit übergeben wird.
Tadhg McDonald-Jensen