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 char not 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.
Na lewo od znaku / (slash) wymagane są argumenty pozycyjne.
Na prawo od znaku gwiazdki * wymagane są argumenty ze słowami kluczowymi.
Pomiędzy znakiem / a znakiem * obie formy argumentów są dozwolone.
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, /)