Przekazywanie argumentów

WPROWADZENIE

Można definiować funkcje ze zmienną liczbą argumentów. Istnieją trzy sposoby, które mogą być ze sobą łączone:

DOMYŚLNE WARTOŚCI ARGUMENTÓW

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]

DOWOLNA LISTA ARGUMENTÓW


# 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']

ARGUMENTY W POSTACI SŁÓW KLUCZOWYCH


# 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

POSTAĆ OGÓLNA

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

ROZPAKOWYWANIE LISTY ARGUMENTÓW


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.

WYMUSZANIE FORMY ARGUMENTÓW (PYTHON 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, /)