Można definiować funkcje ze zmienną liczbą argumentów. Istnieją trzy sposoby, które mogą być ze sobą łączone:
Definicja funkcji jest instrukcją. Argument domyślny jest generowany w chwili wywołania instrukcji def, a nie wywołania funkcji. Dlatego trzeba uważać, jeżeli argument domyślny jest zmienny, jak np. lista czy słownik.
def print_word(word, n=1): """Wypisanie n linii ze słowem word.""" for i in range(n): print("{} {}".format(i, word)) print_word("bla") print_word("bla", 3) print_word(n=4, word="bum") # zastosowanie słów kluczowych
def tester1(x, L=[]): """Lista L rośnie po każdym wywołaniu funkcji.""" L.append(x) print("tester1 {}".format(L)) def tester2(x, L=None): """Lista L domyślnie zawsze pusta.""" if L is None: L = [] L.append(x) print("tester2 {}".format(L)) tester1(1) # [1] tester1(2) # [1, 2] tester1(3) # [1, 2, 3] tester2(1) # [1] tester2(2) # [2] tester2(3) # [3]
# Użycie składni '*identifier'. def print_multiple_items(separator, *arguments): # 'arguments' to krotka do utworzenia """Sklejenie napisów podanym separatorem.""" print(separator.join(arguments)) print_multiple_items("_", "ab", "cde", "f") # ab_cde_f
def union(*arguments): # 'arguments' to krotka do utworzenia """Wypisanie listy wspólnych znaków występujących w napisach.""" result = [] for word in arguments: for char in word: if not char in result: result.append(char) return result print(union("abc", "cde", "efg")) # ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# Użycie składni '**identifier'. def university(**keywords): # 'keywords' to słownik do utworzenia """Wypisanie władz uniwersytetu.""" for key in sorted(keywords): print("{} : {}".format(key, keywords[key])) university(rektor="Nowak", kanclerz="Pedracka", prorektor1="Mania") # kanclerz : Pedracka # prorektor1 : Mania # rektor : Nowak
W wywołaniu funkcji najpierw muszą zostać podane wszystkie argumenty pozycyjne, po których następują wszystkie argumenty ze słowami kluczowymi (name=value), a po nich forma *arguments i na końcu forma **keywords. W nagłówku funkcji kolejność argumentów jest analogiczna.
# Ogólnie funkcja może mieć postać: # def f(a1, a2=v2, *a3, **a4): ... # Przy wywołaniu f(x1, x2, x3, x4, b1=x5, b2=x6) będą podstawienia: # a1=x1, normalny argument pozycyjny # a2=x2, argument dopasowany pozycyjnie # a3=(x3, x4), tu są nadmiarowe argumenty pozycyjne # a4={"b1":x5, "b2":x6}, tu są nadmiarowe argumenty ze słowami kluczowymi
range(3, 6) # [3, 4, 5], zwykłe wywołanie z osobnymi argumentami args = [3, 6] range(*args) # [3, 4, 5], wywołanie z rozpakowaniem argumentów # Tutaj args może być dowolnym obiektem iterowalnym z dwoma elementami.
def describe(name, age=0, position=None): """Wypisanie komunikatu o argumentach.""" print("{} age {} position {}".format(name, age, position)) person = {"name": "Bogdan", "age": 30, "position": "teacher"} describe("Adam", 20, "student") # Adam age 20 position student describe("Bogdan", 30, "teacher") # Bogdan age 30 position teacher # Pobieranie danych ze słownika. describe(person["name"], person["age"], person["position"]) # Zastosowanie słów kluczowych - kolejność argumentów dowolna. describe(name=person["name"], age=person["age"], position=person["position"]) # Rozpakowanie słownika. describe(**person)
W Pythonie 2 istnieje funkcja apply() o podobnym zastosowaniu, ale została usunięta z Pythona 3.
def func(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): pass def func_pos_only(arg, /): pass # func_pos_only(25) def func_kwd_only(*, arg): pass # func_kwd_only(arg=34) #def func(/, arg): pass # SyntaxError #def func(arg, *): pass # SyntaxError # sorted(iterable, /, *, key=None, reverse=False) # abs(x, /)