Ettearvamatu hulk argumente (*args, **kwargs)
¶
Tihti tuleb ette olukordi, kus soovime funktsioonile anda sisse
erineva koguse argumente või nimelisi argumente (keyword arguments).
Seega võib kohata funktsioonide definitsioonides järgnevat kirjapilti:
def bacon(*args, **kwargs)
.
Vaatame kõigepealt *args
(arguments) kasutust. Muutuja nimi ei pea tingimata olema
args
vaid võib vabalt olla ka midagi muud, args
on lihtsalt kujunenud
konventsiooniks. Tärni kasutus muutuja ees lubab saata funktsioonile määramata koguse (nimetuid) argumente.
Soovides luua funktsiooni, mis summeeriks sissetulevad arvud sõltumata
kogusest, peaksime tegema funktsiooni kahe parameetriga, kolme parameetriga jne,
aga *
muutuja ees võimaldab seda mugavalt teha.
# no pec
def sum_all(*numbers: int) -> int:
total = 0
# numbers is a tuple containing all the positional arguments
for numbers in numbers:
total += numbers
return total
print(sum_all(45, 32, 89, 78)) # Prints 244
print(sum_all(2)) # Prints 2
Vaatame veel olukordi, kus lisaks positsioonilistele parameetritele on esimesel funktsioonil ka formaalne parameeter:
# no pec
def multiply(initial: int, *args: int) -> int:
result = initial
for arg in args:
result *= arg
return result
print(multiply(1, 2, 5)) # --> 10
print(multiply(0, 2)) # --> 0
# We can also use the same syntax to unpack
numbers = (1, 2, 3)
print(multiply(1, *numbers)) # --> 6
# no pec
def print_all_args(*args):
print(args)
print_all_args(1) # --> (1,)
print_all_args(1, 2) # --> (1, 2)
print_all_args(5, 'cookie', [13, 14]) # --> (5, 'cookie', [13, 14])
# no pec
def join_numbers(*numbers: int, separator=',') -> str:
"""Join numbers into a string using given separator or default comma."""
return separator.join(map(str, numbers))
print(join_numbers(1, 2, 3)) # --> 1,2,3
print(join_numbers(21, 10, 2018, separator='.')) # --> 21.10.2018
values = [3, 3]
# With a variable
print(join_numbers(*values, separator='|')) # --> 3|3
# Without a variable
print(join_numbers(*(0, 2, 3))) # --> 0,2,3
**kwargs
(keyword arguments) toimib analoogiliselt ja lubab määramata koguses nimelisi argumente.
Samuti pole oluline muutuja nimi, aga muutuja ees peab olema **
.
Kui *args
puhul oli parameetrina tegemist ennikuga (Ennik (tuple)),
siis kwargs-i puhul luuakse sõnastik (Sõnastik (dict)). Vaatame näiteid:
# no pec
def print_kwargs(**kwargs):
print(kwargs)
# A dictionary will be made (not ordered before Python 3.6)
print_kwargs(name='Guido', age=62, is_cool=True)
# Prints {'name': 'Guido', 'age': 62, 'is_cool': True}
# no pec
def print_key_value_pairs(**kwargs):
for key, value in kwargs.items():
print(f'Key: {key}, Value: {value}')
print_key_value_pairs(attack=20, defense=12.5, hasEvolved=False)
# Key: attack, Value: 20
# Key: defense, Value: 12.5
# Key: hasEvolved, Value: False
# The same as above, but pass a dictionary
player_data = {'attack': 20, 'defense': 12.5, 'hasEvolved': False}
print_key_value_pairs(**player_data)
# Key: attack, Value: 20
# Key: defense, Value: 12.5
# Key: hasEvolved, Value: False
# no pec
def foo(arg, *args, kwarg_1=True, **kwargs):
print(arg, args, kwarg_1, kwargs)
# A lot of different ways to pass the same data
foo('a', *(1, 2), kwarg_1=True, other_kwarg=True, y=1)
foo('a', *(1, 2), other_kwarg=True, kwarg_1=True, y=1)
foo('a', *(1, 2), other_kwarg=True, y=1)
foo('a', *[1, 2], **dict(other_kwarg=True, y=1))
foo('a', *[1, 2], **dict([('other_kwarg', True), ('y', 1)]))
kwargs = {
'other_kwarg': True,
'y': 1,
}
args = (1, 2)
foo('a', *args, **kwargs)
# a (1, 2) True {'other_kwarg': True, 'y': 1} is printed 6 times to the console
# Some of these are for demonstration purposes, use the one that is most readable
Nüüd tasub vaadata Python3 sisseehitatud printimise
funktsiooni deklaratsiooni ja aru saada kuidas see tegelikult toimib def print(self, *args, sep=' ', end='\n', file=None)
.