Поиск…


замечания

Здесь есть несколько замечаний:

  1. Названия args и kwargs используются по соглашению, они не являются частью спецификации языка. Таким образом, они эквивалентны:

     def func(*args, **kwargs):
         print(args)
         print(kwargs)
    

     def func(*a, **b):
         print(a)
         print(b)
    
  2. У вас может быть не более одного args или более одного параметра kwargs (однако они не требуются)

     def func(*args1, *args2):
     #   File "<stdin>", line 1
     #     def test(*args1, *args2):
     #                      ^
     # SyntaxError: invalid syntax
    

     def test(**kwargs1, **kwargs2):
     #   File "<stdin>", line 1
     #     def test(**kwargs1, **kwargs2):
     #                       ^
     # SyntaxError: invalid syntax
    
  3. Если какой-либо позиционный аргумент следует за аргументами *args , они являются аргументами только для ключевого слова, которые могут передаваться только по имени. Вместо *args можно использовать одну звезду, чтобы заставить значения использовать аргументы с ключевыми словами, не предоставляя список переменных параметров. Списки параметров только для ключевых слов доступны только в Python 3.

     def func(a, b, *args, x, y):
         print(a, b, args, x, y)
    
     func(1, 2, 3, 4, x=5, y=6)
     #>>> 1, 2, (3, 4), 5, 6
    

     def func(a, b, *, x, y):
         print(a, b, x, y)
    
     func(1, 2, x=5, y=6)
     #>>> 1, 2, 5, 6
    
  4. **kwargs должны быть последними в списке параметров.

     def test(**kwargs, *args):
     #   File "<stdin>", line 1
     #     def test(**kwargs, *args):
     #                      ^
     # SyntaxError: invalid syntax
    

Использование * args при написании функций

Вы можете использовать звезду * при написании функции для сбора всех позиционных (т. Е. Неназванных) аргументов в кортеже:

def print_args(farg, *args):
   print("formal arg: %s" % farg)
   for arg in args:
       print("another positional arg: %s" % arg)

Метод вызова:

print_args(1, "two", 3)

В этом вызове farg будет назначаться как всегда, а два других будут передаваться в корте args в том порядке, в котором они были получены.

Использование ** kwargs при записи функций

Вы можете определить функцию, которая принимает произвольное количество аргументов ключевого слова (named), используя двойную звездочку ** перед именем параметра:

def print_kwargs(**kwargs):
    print(kwargs)

При вызове метода Python будет строить словарь всех аргументов ключевого слова и сделать его доступным в теле функции:

print_kwargs(a="two", b=3)
# prints: "{a: "two", b=3}"

Обратите внимание, что параметр ** kwargs в определении функции всегда должен быть последним параметром, и он будет соответствовать только аргументам, которые были переданы после предыдущих.

def example(a, **kw):
    print kw

example(a=2, b=3, c=4) # => {'b': 3, 'c': 4}

Внутри тела функции kwargs манипулируют так же, как словарь; для доступа к отдельным элементам в kwargs вы просто просматриваете их так же, как и с обычным словарем:

def print_kwargs(**kwargs):
    for key in kwargs:
        print("key = {0}, value = {1}".format(key, kwargs[key])) 

Теперь вызов print_kwargs(a="two", b=1) показывает следующий вывод:

print_kwargs(a = "two", b = 1)
key = a, value = "two"
key = b, value = 1

Использование * args при вызове функций

Общим примером использования *args в определении функции является делегирование обработки либо завернутой, либо унаследованной функции. Типичный пример может быть в методе __init__ класса

class A(object):
    def __init__(self, b, c):
        self.y = b
        self.z = c

class B(A):
    def __init__(self, a, *args, **kwargs):
        super(B, self).__init__(*args, **kwargs)
        self.x = a

Здесь параметр обрабатывается дочерний класс после того, как все другие аргументы (позиционные и ключевые слова) передаются на - и обрабатываются - базового класса. a

Например:

b = B(1, 2, 3)
b.x  # 1
b.y  # 2
b.z  # 3

Здесь происходит функция класса B __init__ которая видит аргументы 1, 2, 3 . Он знает, что ему нужно взять один позиционный аргумент ( a ), поэтому он захватывает первый аргумент, переданный в ( 1 ), поэтому в области функции a == 1 .

Затем он видит, что ему нужно принять произвольное количество позиционных аргументов ( *args ), чтобы он оставил остальные позиционные аргументы, переданные в ( 1, 2 ), и наполнил их в *args . Теперь (в рамках функции) args == [2, 3] .

Затем он вызывает функцию __init__ класса A с *args . Python видит * перед args и «распаковывает» список в аргументы. В этом примере, когда класс B 's __init__ вызовов функций класса A ' s __init__ функцию, оно будет передано аргументы 2, 3 (т.е. A(2, 3) ).

Наконец, он устанавливает собственное свойство x в первый позиционный аргумент a , равный 1 .

Использование ** kwargs при вызове функций

Вы можете использовать словарь для назначения значений параметрам функции; используя имя параметра в качестве ключей в словаре и значение этих аргументов, привязанных к каждому ключу:

def test_func(arg1, arg2, arg3): # Usual function with three arguments
   print("arg1: %s" % arg1)
   print("arg2: %s" % arg2)
   print("arg3: %s" % arg3)

# Note that dictionaries are unordered, so we can switch arg2 and arg3. Only the names matter.
kwargs = {"arg3": 3, "arg2": "two"}

# Bind the first argument (ie. arg1) to 1, and use the kwargs dictionary to bind the others
test_var_args_call(1, **kwargs) 

Использование * args при вызове функций

Эффект использования оператора * при аргументе при вызове функции заключается в распаковке списка или аргумента кортежа

def print_args(arg1, arg2):
    print(str(arg1) + str(arg2))

a = [1,2]
b = tuple([3,4])

print_args(*a)
# 12
print_args(*b)
# 34

Обратите внимание, что длина помеченного аргумента должна быть равна числу аргументов функции.

Общей идиомой python является использование оператора распаковки * с zip функцией для изменения его эффектов:

a = [1,3,5,7,9]
b = [2,4,6,8,10]

zipped = zip(a,b)
# [(1,2), (3,4), (5,6), (7,8), (9,10)]

zip(*zipped)
# (1,3,5,7,9), (2,4,6,8,10)

Ключевое слово и требуемые по ключу аргументы

Python 3 позволяет вам определять аргументы функции, которые могут быть назначены только по ключевым словам, даже без значений по умолчанию. Это делается с помощью star * для использования дополнительных позиционных параметров без установки параметров ключевого слова. Все аргументы после * являются ключевыми словами (то есть непозиционными) аргументами. Обратите внимание, что если аргументы только для ключевого слова не заданы по умолчанию, они все равно необходимы при вызове функции.

def print_args(arg1, *args, keyword_required, keyword_only=True):
    print("first positional arg: {}".format(arg1))
    for arg in args:
        print("another positional arg: {}".format(arg))
    print("keyword_required value: {}".format(keyword_required))
    print("keyword_only value: {}".format(keyword_only))
    
print(1, 2, 3, 4) # TypeError: print_args() missing 1 required keyword-only argument: 'keyword_required'
print(1, 2, 3, keyword_required=4) 
# first positional arg: 1
# another positional arg: 2
# another positional arg: 3
# keyword_required value: 4
# keyword_only value: True

Заполнение значений kwarg со словарем

def foobar(foo=None, bar=None):
    return "{}{}".format(foo, bar)

values = {"foo": "foo", "bar": "bar"}

foobar(**values) # "foobar"

** kwargs и значения по умолчанию

Использовать значения по умолчанию с ** kwargs

def fun(**kwargs):
    print kwargs.get('value', 0)

fun()
# print 0
fun(value=1)
# print 1


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow