2011-01-12 3 views
8

Kann eine beliebige Anzahl von benannten Standardargumenten bedingt an eine Python-Funktion übergeben werden?Bedingte Weitergabe einer beliebigen Anzahl von benannten Standardargumenten an eine Funktion

Für z. gibt es eine Funktion:

def func(arg, arg2='', arg3='def') 

Jetzt Logik ist, dass ich eine Bedingung, die bestimmt, ob arg3 weitergegeben werden muss, ich es wie folgt tun:

if condition == True: 
    func('arg', arg2='arg2', arg3='some value') 
else: 
    func('arg', arg2='arg2') 

Frage ist, kann ich eine Kurz wie:

func('arg', 'arg2', 'some value' if condition == True else # nothing so default gets picked 
) 

Antwort

5

Die einzige Art, wie ich denken kann, wäre

func("arg", "arg2", **({"arg3": "some value"} if condition == True else {})) 

oder

func("arg", "arg2", *(("some value",) if condition == True else())) 

aber bitte dies nicht tun. Verwenden Sie den Code, den Sie selbst zur Verfügung gestellt, oder etwas ähnliches:

if condition: 
    arg3 = "some value", 
else: 
    arg3 =() 
func("arg", "arg2", *arg3) 
+2

Was hast du gegen ** und *? – Erin

+2

Nichts gegen '*' und '**'. Ich denke nur, dass der ursprüngliche Code lesbarer ist. Ich glaube, ich mag kein "a if c else b". –

+0

Alternativ könnte eine bedingte Logik (außerhalb des Funktionsaufrufs) verwendet werden, um ein Argumentwörterbuch zu erstellen.Sie könnten dann mit '**' übergeben werden. Dies bleibt mit einer größeren Anzahl von Argumenten lesbar. – Wilduck

8

, die keine gültigen Python-Syntax Sie etwas nach else haben haben würde. Was geschehen ist, ist normalerweise:

func('arg', 'arg2', 'some value' if condition else None) 

und Funktionsdefinition wird entsprechend geändert:

def func(arg, arg2='', arg3=None): 
    arg3 = 'def' if arg3 is None else arg3 
1

Wenn Sie eine Funktion haben, die eine Menge von Standardargumente

def lots_of_defaults(arg1 = "foo", arg2 = "bar", arg3 = "baz", arg4 = "blah"): 
    pass 

hat und Sie möchten Übergeben Sie verschiedene Werte an einige von diesen, basierend auf etwas anderes in Ihrem Programm, ein einfacher Weg ist, ** zu verwenden, um ein Wörterbuch von Argumentnamen und Werten, die Sie aufgebaut haben, zu entpacken ed auf Ihrer Programmlogik.

different_than_defaults = {} 
if foobar: 
    different_than_defaults["arg1"] = "baaaz" 
if barblah: 
    different_than_defaults["arg4"] = "bleck" 

lots_of_defaults(**different_than_defaults) 

Dies hat den Vorteil, nicht den Code an der Stelle verstopfen Ihrer Funktion aufrufen, wenn es eine Menge Logik bestimmen, was in Ihren Anruf geht. Sie müssen vorsichtig sein, wenn Sie Argumente haben, die keine Standardwerte haben, um die Werte, die Sie übergeben, mit einzuschließen, bevor Sie Ihr Wörterbuch übergeben.

0

Sie können eine Hilfsfunktion

def caller(func, *args, **kwargs): 
    return func(*args, **{k:v for k,v in kwargs.items() if v != caller.DONT_PASS}) 
caller.DONT_PASS = object() 

Mit dieser Funktion eine andere Funktion aufzurufen und caller.DONT_PASS Argumente festlegen, schreiben, die Sie nicht wollen, zu übergeben.

caller(func, 'arg', 'arg2', arg3 = 'some value' if condition else caller.DONT_PASS) 

Beachten Sie, dass diese caller() nur Unterstützung Schlüsselwort Argumente bedingt vorbei. Um Positionsargumente zu unterstützen, müssen Sie möglicherweise das Modul inspect verwenden, um die Funktion zu überprüfen.

Verwandte Themen