2012-03-01 9 views
6

Mam funkcję Pythona, która wymaga wielu parametrów, z których jednym jest rodzaj symulacji do wykonania. Na przykład, opcje mogą być „słonecznej”, „Widok” lub „zarównoPythoniczny sposób na wybór 2-3 opcji jako argumentu do funkcji

Co to jest pythonic sposób, aby umożliwić użytkownikowi ustawić te

widzę różne opcje:.?

  1. użyć zmiennej ciąg i sprawdź to - tak byłoby func(a, b, c, type='solar')

  2. Ustaw pewne stałe w klasie i używać func(a, b, c, type=classname.SOLAR)

  3. Jeśli są tylko dwie opcje (jak to jest w przypadku niektórych moich funkcji) zmuś go do argumentu Prawda/Fałsz, używając czegoś takiego jak func(a, b, c, do_solar=False), aby uzyskać opcję "widoku".

Jakieś preferencje (lub inne pomysły) na temat Pythonicznych sposobów robienia tego?

+2

Nie należy stosować 'type' jak nazwa argumentu, ponieważ jest to wbudowany ... –

Odpowiedz

3

Nie podoba mi się żadna z tych opcji.

Chciałbym zdefiniować dwie różne funkcje, perform_solar(a, b, c) i perform_view(a, b, c) i pozwolić dzwoniącemu zdecydować, których z nich chce użyć, w jakiej kolejności iz którymi argumentami.

Jeśli powodem, dla którego uważasz, że musisz spakować je w jedną funkcję, jest to, że współużytkują stan, powinieneś udostępnić ten stan w obiekcie i zdefiniować funkcje jako metody.

1

Można użyć opcjonalnych (słowo kluczowe) Argumenty jak ten

def func(a, b, c, **kw): 
    if kw.get('do_solar'): 
     # Do Solar 
    if kw.get('do_view'): 
     # Do view 
3

Jeśli punkt Niklas' sprawia, że ​​w his answer nie posiada, chciałbym użyć argumentu ciąg. Istnieją moduły Pythona w standardowej bibliotece, które używają podobnych argumentów. Na przykład csv.reader().

sim_func(a, b, c, sim_type='solar') 

Pamiętaj, aby podać rozsądny błąd w funkcji, który pomaga osobom, które wpisują coś niewłaściwego.

def sim_func(a, b, c, sim_type='solar'): 
    sim_types = ['solar', 'view', 'both'] 
    if sim_type not in sim_types: 
     raise ValueError("Invalid sim type. Expected one of: %s" % sim_types) 
    ... 
2

Ponieważ funkcje są obiekty w Pythonie, można rzeczywiście procesowe * args jako lista metod i przekazać rodzaje symulacji jako arbitratry args na końcu. Miałoby to tę zaletę, że pozwala na definiowanie nowych symulacji w przyszłości bez konieczności refaktoryzacji tego kodu.

def func(a, b, c, *args): 
    for arg in args: 
     arg(a, b, c) 

def foosim(a, b, c): 
    print 'foosim %d' % (a + b + c) 

def barsim(a, b, c): 
    print 'barsim %d' % (a * b * c) 

Zastosowanie:

func(2, 2, 3, foosim) 
func(2, 2, 3, barsim) 
func(2, 2, 3, foosim, barsim) 

wyjściowa:

foosim 7 
barsim 12 
foosim 7 
barsim 12 
+0

jestem nie ma adwokata języka, ale widziałem to podejście w dobrym kodzie. To wymaga, aby twoje symulacje były oddzielnymi funkcjami, co i tak jest dobrym pomysłem: dobre konwencje zachęcają do dobrego programowania. – alexis