Jak utworzyć funkcję Python z opcjonalnymi argumentami?

219

Mam funkcję Python, która pobiera kilka argumentów. Niektóre z tych argumentów można pominąć w niektórych scenariuszach.

def some_function (self, a, b, c, d = None, e = None, f = None, g = None, h = None):
    #code

Argumenty dza hsą ciągi których każdy ma różne znaczenia. Ważne jest, że mogę wybrać opcjonalne parametry do przekazania w dowolnej kombinacji. Na przykład, (a, b, C, d, e)lub (a, b, C, g, h), lub (a, b, C, d, e, f, lub wszystkie z nich (to są moje wybory).

Byłoby wspaniale, gdybym mógł przeciążyć funkcję - ale przeczytałem, że Python nie obsługuje przeciążania. Próbowałem wstawić niektóre wymagane argumenty int na liście - i wystąpił błąd niedopasowania argumentu.

W tej chwili wysyłam puste ciągi zamiast kilku pierwszych brakujących argumentów jako symbole zastępcze. Chciałbym móc wywoływać funkcję przy użyciu rzeczywistych wartości.

Czy jest na to sposób? Czy mogę przekazać listę zamiast listy argumentów?

W tej chwili prototyp używający ctypów wygląda mniej więcej tak:

_fdll.some_function.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]
Thalia
źródło

Odpowiedzi:

196

Spróbuj nazywając go tak: obj.some_function( '1', 2, '3', g="foo", h="bar" ). Po wymaganych argumentach pozycyjnych można podać konkretne opcjonalne argumenty według nazwy.

Russell Borogove
źródło
246

Wystarczy użyć *argsparametru, który pozwala przekazać tyle argumentów, ile chcesz po swoim a,b,c. Trzeba by dodać trochę logiki do mapy args-> c,d,e,fale to „sposób” przeciążenia.

def myfunc(a,b, *args, **kwargs):
   for ar in args:
      print ar
myfunc(a,b,c,d,e,f)

I wydrukuje wartości c,d,e,f


Podobnie możesz użyć kwargsargumentu, a następnie nazwać swoje parametry.

def myfunc(a,b, *args, **kwargs):
      c = kwargs.get('c', None)
      d = kwargs.get('d', None)
      #etc
myfunc(a,b, c='nick', d='dog', ...)

A następnie kwargsmiałby słownik wszystkich parametrów, po których kluczowa jest wartośća,b

Nic
źródło
Dziękuję Ci. Chociaż nie mogę użyć tak dużej elastyczności w kodzie i nie rozwiązuje to problemu wywoływania z różnymi pustymi dziurami na mojej liście, jest to świetne narzędzie do użycia w innym projekcie. a Russel Borogove dał mi dokładną odpowiedź, której potrzebowałem dla mojego problemu, jestem szczęśliwy.
Thalia
12
Nazywa się to Arbitrary Argument Lists
FabienB
@Nix, naprawdę podoba mi się twoja odpowiedź. Czy możesz jednak wyjaśnić, do czego c = kwargs.get('c', None)służy to oświadczenie ? Czy jest wymagany we wszystkich funkcjach, które mają opcjonalne argumenty? W twoim kodzie masz tylko 2 opcjonalne argumenty. Co jeśli użytkownik chce powiedzieć inny argument e? Jak mogę zmienić swój przykładowy kod dla każdej nieznanej liczby opcjonalnych args, ex: def my_func(a, b, *args, **kwagars): obj = <do something with a & b> obj.add(c) obj.add(d) continue obj.add(for e, f, g...)? Czy muszę to c = kwargs.get('c', None) etczrobić przed wykonaniem obj.add(c, d, ...)?
Nemo
Jeśli martwisz się złożonością czasu. To byłby problem
NduJay