2011-01-12 12 views
8

Czy można warunkowo przekazać dowolną liczbę nazwanych domyślnych argumentów do funkcji Python?Warunkowe przekazywanie dowolnej liczby domyślnie nazwanych argumentów do funkcji

Na przykład. istnieje funkcja:

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

Teraz logika jest, że mam warunek, który określa, czy arg3 należy przekazać, mogę to zrobić tak:

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

Pytanie brzmi, czy mogę mieć skrót jak:

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

Odpowiedz

5

jedynym sposobem mogę myśleć byłoby

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

lub

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

ale proszę nie rób tego. Użyj kodu podanego siebie, czy coś takiego:

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

Co takiego masz przeciwko ** i *? – Erin

+2

Nic przeciwko '*' i '**'. Po prostu uważam, że oryginalny kod jest bardziej czytelny. Myślę, że nie lubię "a if c else b". –

+0

Alternatywnie, można użyć logiki warunkowej (poza wywołaniem funkcji) do skonstruowania słownika argumentów.Następnie można je przekazać za pomocą '**'. Pozostaje czytelny przy większej liczbie argumentów. – Wilduck

8

które nie byłyby ważne składni Pythona trzeba mieć coś po else. Co odbywa się normalnie jest:

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

i definicja funkcja zostanie odpowiednio zmieniona:

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

Jeśli masz funkcję, która ma wiele domyślnych argumentów

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

i chcesz przekazywać różne wartości do niektórych z nich, w oparciu o coś innego, co dzieje się w twoim programie, prostym sposobem jest użycie ** do rozpakowania słownika nazw argumentów i wartości, które stworzyłeś ed w logice programu.

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

lots_of_defaults(**different_than_defaults) 

Ma to tę zaletę, nie zatykanie się kod w punkcie wywołaniem funkcji, jeśli jest dużo logiki określania tego, co dzieje się w rozmowy. Musisz być ostrożny, jeśli masz jakieś argumenty, które nie mają wartości domyślnych, aby uwzględnić wartości, które przekazujesz przed przekazaniem słownika.

0

Można napisać funkcję pomocnika

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

użyć tej funkcji, aby zadzwonić do innej funkcji i korzystania caller.DONT_PASS określić argumenty, które nie chcą przechodzić.

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

Należy pamiętać, że ta caller() obsługuje tylko warunkowo przekazywanie argumentów słów kluczowych. Aby obsłużyć argumenty pozycyjne, może być konieczne użycie modułu inspect do sprawdzenia funkcji.

Powiązane problemy