Hoe variabele lengte argumenten (*args, **kwargs) gebruiken in Python

Bedrijf

De volgende functieargumenten zijn waarschijnlijk de meest voorkomende die je tegen de borst stuiten als je naar Python code kijkt en zegt, “Wat is dit?

  • *args
  • **kwargs

Een willekeurig aantal argumenten (argumenten met variabele lengte) kan worden gespecificeerd door een sterretje toe te voegen aan het argument in de functiedefinitie, als volgt

  • *
  • **

De namen *args,**kwargs worden vaak als conventie gebruikt. Andere namen zijn echter aanvaardbaar zolang * en ** aan het begin staan. De volgende voorbeeldcode gebruikt de namen *args,**kwargs.

De volgende details worden hieronder beschreven.

  • *args:Accepteert meerdere argumenten als een tupel
  • **kwargs:Accepteert meerdere trefwoordargumenten als een woordenboek

*args: Accepteert meerdere argumenten als een tupel

Een willekeurig aantal argumenten kan worden gespecificeerd door argumenten te definiëren met *, zoals in *args.

def my_sum(*args):
    return sum(args)

print(my_sum(1, 2, 3, 4))
# 10

print(my_sum(1, 2, 3, 4, 5, 6, 7, 8))
# 36

Meerdere argumenten worden als een tupel in de functie ontvangen. In het voorbeeld wordt aan de functie sum() een tupel doorgegeven om de som te berekenen.

def my_sum2(*args):
    print('args: ', args)
    print('type: ', type(args))
    print('sum : ', sum(args))

my_sum2(1, 2, 3, 4)
# args:  (1, 2, 3, 4)
# type:  <class 'tuple'>
# sum :  10

Het kan ook worden gecombineerd met een positieargument.

De waarde gespecificeerd na (rechts van) het positionele argument wordt doorgegeven aan args als een tupel. Als er alleen een positioneel argument is, is het een leeg tupel.

def func_args(arg1, arg2, *args):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

func_args(0, 1, 2, 3, 4)
# arg1:  0
# arg2:  1
# args:  (2, 3, 4)

func_args(0, 1)
# arg1:  0
# arg2:  1
# args:  ()

Argumenten gemarkeerd met * mogen eerst gedefinieerd worden. In dat geval echter moeten argumenten die later dan *args worden gedefinieerd in trefwoordvorm worden gespecificeerd. Het trefwoordformaat is overigens de “argument name = value” vorm.

De laatste waarde wordt niet automatisch doorgegeven aan het positionele argument. Indien het niet als sleutelwoord-argument wordt gespecificeerd, zal een TypeError-foutmelding het gevolg zijn.

def func_args2(arg1, *args, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('args: ', args)

# func_args2(0, 1, 2, 3, 4)
# TypeError: func_args2() missing 1 required keyword-only argument: 'arg2'

func_args2(0, 1, 2, 3, arg2=4)
# arg1:  0
# arg2:  4
# args:  (1, 2, 3)

Als alleen * argumenten worden opgegeven, moeten de volgende argumenten altijd als trefwoordargumenten worden opgegeven.(keyword-only argument)

def func_args_kw_only(arg1, *, arg2):
    print('arg1: ', arg1)
    print('arg2: ', arg2)

# func_args_kw_only(100, 200)
# TypeError: func_args_kw_only() takes 1 positional argument but 2 were given

func_args_kw_only(100, arg2=200)
# arg1:  100
# arg2:  200

**kwargs: Accepteert meerdere trefwoordargumenten als een woordenboek

Een willekeurig aantal trefwoord-argumenten kan worden gespecificeerd door argumenten te definiëren met ,** zoals in **kwargs.

In de functie wordt de naam van het argument ontvangen als een woordenboek waarvan de sleutel de key is en waarvan de waarde de value is.

def func_kwargs(**kwargs):
    print('kwargs: ', kwargs)
    print('type: ', type(kwargs))

func_kwargs(key1=1, key2=2, key3=3)
# kwargs:  {'key1': 1, 'key2': 2, 'key3': 3}
# type:  <class 'dict'>

Het kan ook worden gebruikt in combinatie met een positieargument.

def func_kwargs_positional(arg1, arg2, **kwargs):
    print('arg1: ', arg1)
    print('arg2: ', arg2)
    print('kwargs: ', kwargs)

func_kwargs_positional(0, 1, key1=1)
# arg1:  0
# arg2:  1
# kwargs:  {'key1': 1}

Door het woordenboekobject met ** als argument te specificeren bij het aanroepen van de functie, is het mogelijk het uit te breiden en het als het respectieve argument door te geven.

d = {'key1': 1, 'key2': 2, 'arg1': 100, 'arg2': 200}

func_kwargs_positional(**d)
# arg1:  100
# arg2:  200
# kwargs:  {'key1': 1, 'key2': 2}

Argumenten gemarkeerd met ** mogen enkel gedefinieerd worden op het einde van het argument. Het definiëren van een ander argument na het argument gemarkeerd met ** zal resulteren in een SyntaxError fout.

# def func_kwargs_error(**kwargs, arg):
#     print(kwargs)

# SyntaxError: invalid syntax