python переменное - * args и ** kwargs?




число параметров (10)

Вот одно из моих любимых мест для использования синтаксиса ** как в последнем примере Дейва Вебба:

mynum = 1000
mystr = 'Hello World!'
print "{mystr} New-style formatting is {mynum}x more fun!".format(**locals())

Я не уверен, что это ужасно быстро, если сравнивать с самими именами, но это намного проще набрать!

Поэтому я испытываю трудности с концепцией *args и **kwargs .

До сих пор я узнал, что:

  • *args = список аргументов - как позиционные аргументы
  • **kwargs = dictionary - ключи которых становятся отдельными аргументами ключевого слова, а значения становятся значениями этих аргументов.

Я не понимаю, для какой задачи программирования это было бы полезно.

Может быть:

Я думаю, чтобы вводить списки и словари в качестве аргументов функции И в то же время, что и подстановочный знак, поэтому я могу передать ЛЮБОЙ аргумент?

Есть ли простой пример, чтобы объяснить, как используются *args и **kwargs ?

Также в учебнике, который я нашел, использовалось только «*» и имя переменной.

Являются ли *args и **kwargs только заполнителями или вы используете точно *args и **kwargs в коде?


Представьте, что у вас есть функция, но вы не хотите ограничивать количество параметров, которые она принимает. Пример:

>>> import operator
>>> def multiply(*args):
...  return reduce(operator.mul, args)

Затем вы используете эту функцию:

>>> multiply(1,2,3)
6

or

>>> numbers = [1,2,3]
>>> multiply(*numbers)
6

Имена *args и **kwargs или **kw являются чисто условными. Это облегчает нам чтение кода друг друга

Одно место удобно использовать при использовании структурного модуля

struct.unpack() возвращает кортеж, тогда как struct.pack() использует переменное количество аргументов. При манипулировании данными удобно иметь возможность передавать кортеж в struck.pack() например.

tuple_of_data = struct.unpack(format_str, data)
... manipulate the data
new_data = struct.pack(format_str, *tuple_of_data)

без этой способности вы были бы вынуждены писать

new_data = struct.pack(format_str, tuple_of_data[0], tuple_of_data[1], tuple_of_data[2],...)

что также означает, что если изменяется формат_str и изменяется размер кортежа, мне придется вернуться и отредактировать эту действительно длинную строку


Эти параметры обычно используются для прокси-функций, поэтому прокси-сервер может передать любой входной параметр целевой функции.

def foo(bar=2, baz=5):
    print bar, baz

def proxy(x, *args, **kwargs): # reqire parameter x and accept any number of additional arguments
    print x
    foo(*args, **kwargs) # applies the "non-x" parameter to foo

proxy(23, 5, baz='foo') # calls foo with bar=5 and baz=foo
proxy(6)# calls foo with its default arguments
proxy(7, bar='asdas') # calls foo with bar='asdas' and leave baz default argument

Но поскольку эти параметры скрывают фактические имена параметров, лучше их избегать.


* args и ** kwargs являются специальными магическими функциями Python. Подумайте о функции, которая может иметь неизвестное количество аргументов. Например, по каким-либо причинам вы хотите иметь функцию, которая суммирует неизвестное количество чисел (и вы не хотите использовать встроенную функцию sum). Таким образом, вы пишете эту функцию:

def sumFunction(*args):
  result = 0
  for x in args:
    result += x
  return result

и использовать его как: sumFunction (3,4,6,3,6,8,9).

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

def someFunction(**kwargs):
  if 'text' in kwargs:
    print kwargs['text']

Вызов someFunction (text = "foo") будет печатать foo.


Одно место, где использование *args и **kwargs весьма полезно, относится к подклассу.

class Foo(object):
    def __init__(self, value1, value2):
        # do something with the values
        print value1, value2

class MyFoo(Foo):
    def __init__(self, *args, **kwargs):
        # do something else, don't care about the args
        print 'myfoo'
        super(MyFoo, self).__init__(*args, **kwargs)

Таким образом, вы можете расширить поведение класса Foo, не зная слишком много о Foo. Это может быть весьма удобно, если вы программируете API, который может измениться. MyFoo просто передает все аргументы классу Foo.


Синтаксис - это * и ** . Имена *args и **kwargs только по соглашению, но нет жесткого требования использовать их.

Вы бы использовали *args когда не знаете, сколько аргументов может быть передано вашей функции, то есть вы можете передать произвольное количество аргументов вашей функции. Например:

>>> def print_everything(*args):
        for count, thing in enumerate(args):
...         print( '{0}. {1}'.format(count, thing))
...
>>> print_everything('apple', 'banana', 'cabbage')
0. apple
1. banana
2. cabbage

Аналогично, **kwargs позволяет обрабатывать именованные аргументы, которые вы не определили заранее:

>>> def table_things(**kwargs):
...     for name, value in kwargs.items():
...         print( '{0} = {1}'.format(name, value))
...
>>> table_things(apple = 'fruit', cabbage = 'vegetable')
cabbage = vegetable
apple = fruit

Вы можете использовать их вместе с именованными аргументами. Явные аргументы сначала получают значения, а затем все остальные передаются в *args и **kwargs . Именованные аргументы входят в список. Например:

def table_things(titlestring, **kwargs)

Вы также можете использовать оба параметра в одном и том же определении функции, но *args должно происходить до **kwargs .

Вы также можете использовать синтаксис * и ** при вызове функции. Например:

>>> def print_three_things(a, b, c):
...     print( 'a = {0}, b = {1}, c = {2}'.format(a,b,c))
...
>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
a = aardvark, b = baboon, c = cat

Как вы можете видеть, в этом случае он берет список (или кортеж) предметов и распаковывает его. Под этим он сопоставляет их с аргументами в функции. Конечно, вы можете иметь * как в определении функции, так и в вызове функции.


Вот пример, который использует 3 разных типа параметров.

def func(required_arg, *args, **kwargs):
    # required_arg is a positional-only parameter.
    print required_arg

    # args is a tuple of positional arguments,
    # because the parameter name has * prepended.
    if args: # If args is not empty.
        print args

    # kwargs is a dictionary of keyword arguments,
    # because the parameter name has ** prepended.
    if kwargs: # If kwargs is not empty.
        print kwargs

>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() takes at least 1 argument (0 given)

>>> func("required argument")
required argument

>>> func("required argument", 1, 2, '3')
required argument
(1, 2, '3')

>>> func("required argument", 1, 2, '3', keyword1=4, keyword2="foo")
required argument
(1, 2, '3')
{'keyword2': 'foo', 'keyword1': 4}

Вы можете посмотреть документы python (docs.python.org в FAQ), но более конкретно для хорошего объяснения таинственные мисс args и mister kwargs (любезно предоставлены archive.org) (оригинальная, мертвая ссылка здесь ).

В двух словах оба используются, когда используются необязательные параметры для функции или метода. Как говорит Дэйв, * args используется, когда вы не знаете, сколько аргументов может быть передано, и ** kwargs, когда вы хотите обрабатывать параметры, указанные по имени и значению, как в:

myfunction(myarg=1)

Проверьте модуль epub . Это похоже на простой вариант.





python args kwargs