Cum se utilizează argumente de lungime variabilă (*args, **kwargs) în Python

Afaceri

Următoarele argumente ale funcțiilor sunt probabil cele mai comune argumente care vă pun în dificultate atunci când vă uitați la codul Python și spuneți: „Ce este asta?

  • *args
  • **kwargs

Orice număr de argumente (argumente de lungime variabilă) poate fi specificat prin adăugarea unui asterisc la argumentul din definiția funcției, după cum urmează

  • *
  • **

Denumirile *args,**kwargs sunt adesea folosite ca o convenție. Cu toate acestea, se acceptă și alte denumiri, atâta timp cât * și ** se află la început. Următorul exemplu de cod utilizează numele *args,**kwargs.

Următoarele detalii sunt descrise mai jos.

  • *args:Acceptă mai multe argumente sub forma unui tandem
  • **kwargs:Acceptă mai multe argumente de cuvinte cheie ca un dicționar

*args: Acceptă mai multe argumente sub forma unui tandem

Un număr arbitrar de argumente poate fi specificat prin definirea argumentelor cu *, ca în *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

Argumentele multiple sunt primite ca un tupluș în funcție. În exemplu, funcției sum() i se transmite un tupluplu pentru a calcula suma.

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

De asemenea, poate fi combinat cu un argument de poziție.

Valoarea specificată după (la dreapta) argumentul pozițional este transmisă la args sub formă de tuple. În cazul în care există doar un argument pozițional, acesta este un tupluplu gol.

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:  ()

Argumentele marcate cu * pot fi definite mai întâi. În acest caz, însă, argumentele definite mai târziu de *args trebuie să fie specificate sub formă de cuvinte cheie. De altfel, formatul cuvintelor cheie este forma „nume argument = valoare”.

Ultima valoare nu este transmisă automat la argumentul pozițional. Prin urmare, dacă nu este specificată ca argument de cuvânt cheie, se va produce o eroare de tip TypeError.

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)

În cazul în care sunt specificate numai * argumente, argumentele ulterioare trebuie să fie întotdeauna specificate ca argumente de tip cuvânt cheie.(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: Acceptă mai multe argumente de cuvinte cheie ca un dicționar

Se poate specifica un număr arbitrar de argumente de tip cuvânt cheie prin definirea argumentelor cu ,** ca în **kwargs.

În funcție, numele argumentului este primit sub forma unui dicționar a cărui cheie este cheia și a cărui valoare este valoarea.

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

De asemenea, poate fi utilizat împreună cu un argument de poziție.

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}

Prin specificarea obiectului dicționar cu ** ca argument la apelarea funcției, este posibilă extinderea acestuia și transmiterea lui ca argument respectiv.

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

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

Argumentele marcate cu ** pot fi definite numai la sfârșitul argumentului. Dacă se definește un alt argument după argumentul marcat cu **, se va produce o eroare de sintaxă (SyntaxError).

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

# SyntaxError: invalid syntax
Copied title and URL