Что такое args и kwargs в python
Перейти к содержимому

Что такое args и kwargs в python

  • автор:

Что такое *args и **kwargs в Python?

Функции — это жизнь. Правда? Если вы только начали осваивать Python, неважно — первый ли это ваш язык программирования, или вы пришли в Python из другого языка, то вы уже знаете о том, что количество параметров в объявлении функции соответствует количеству аргументов, которые передают функции при вызове.

Это — основы. Это то, что помогает людям понимать окружающий мир. Но утверждение «количество параметров равно количеству аргументов» закладывает в голову новичка бомбу замедленного действия, которая срабатывает после того, как он увидит в объявлении функции таинственные конструкции *args или **kwargs .

Не позволяйте всяким значкам загонять себя в ступор. Тут нет ничего архисложного. В общем-то, если эти конструкции вам незнакомы — предлагаю с ними разобраться.

Позиционные и именованные аргументы

Для того чтобы разобраться с *args и **kwargs , нам нужно освоить концепции позиционных (positional) и именованных (keyword) аргументов.

Сначала поговорим о том, чем они отличаются. В простейшей функции мы просто сопоставляем позиции аргументов и параметров. Аргумент №1 соответствует параметру №1, аргумент №2 — параметру №2 и так далее.

Для вызова функции необходимы все три аргумента. Если пропустить хотя бы один из них — будет выдано сообщение об ошибке.

Если при объявлении функции назначить параметру значение по умолчанию — указывать соответствующий аргумент при вызове функции уже необязательно. Параметр становится опциональным.

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

В следующем примере установим три параметра в значение по умолчанию None и взглянем на то, как их можно назначать, используя их имена и не обращая внимания на порядок следования аргументов, применяемых при вызове функции.

Оператор «звёздочка»

Оператор * чаще всего ассоциируется у людей с операцией умножения, но в Python он имеет и другой смысл.

Этот оператор позволяет «распаковывать» объекты, внутри которых хранятся некие элементы. Вот пример:

Тут берётся содержимое списка a , распаковывается, и помещается в список b .

Как пользоваться *args и **kwargs

Итак, мы знаем о том, что оператор «звёздочка» в Python способен «вытаскивать» из объектов составляющие их элементы. Знаем мы и о том, что существует два вида параметров функций. Вполне возможно, что вы уже додумались до этого сами, но я, на всякий случай, скажу об этом. А именно, *args — это сокращение от «arguments» (аргументы), а **kwargs — сокращение от «keyword arguments» (именованные аргументы).

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

Я не использовал при объявлении функции конструкцию *args . Вместо неё у меня — *scores . Нет ли тут ошибки? Ошибки здесь нет. Дело в том, что «args» — это всего лишь набор символов, которым принято обозначать аргументы. Самое главное тут — это оператор * . А то, что именно идёт после него, особой роли не играет. Благодаря использованию * мы создали список позиционных аргументов на основе того, что было передано функции при вызове.

После того, как мы разобрались с *args , с пониманием **kwargs проблем быть уже не должно. Имя, опять же, значения не имеет. Главное — это два символа ** . Благодаря им создаётся словарь, в котором содержатся именованные аргументы, переданные функции при её вызове.

Итоги

Вот несколько советов, которые помогут вам избежать распространённых проблем, возникающих при работе с функциями, и расширить свои знания:

Python args and kwargs: Demystified

Sometimes, when you look at a function definition in Python, you might see that it takes two strange arguments: *args and **kwargs . If you’ve ever wondered what these peculiar variables are, or why your IDE defines them in main() , then this article is for you. You’ll learn how to use args and kwargs in Python to add more flexibility to your functions.

By the end of the article, you’ll know:

  • What *args and **kwargs actually mean
  • How to use *args and **kwargs in function definitions
  • How to use a single asterisk ( * ) to unpack iterables
  • How to use two asterisks ( ** ) to unpack dictionaries

This article assumes that you already know how to define Python functions and work with lists and dictionaries.

Free Bonus: Click here to get a Python Cheat Sheet and learn the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.

Passing Multiple Arguments to a Function

*args and **kwargs allow you to pass multiple arguments or keyword arguments to a function. Consider the following example. This is a simple function that takes two arguments and returns their sum:

This function works fine, but it’s limited to only two arguments. What if you need to sum a varying number of arguments, where the specific number of arguments passed is only determined at runtime? Wouldn’t it be great to create a function that could sum all the integers passed to it, no matter how many there are?

Using the Python args Variable in Function Definitions

There are a few ways you can pass a varying number of arguments to a function. The first way is often the most intuitive for people that have experience with collections. You simply pass a list or a set of all the arguments to your function. So for my_sum() , you could pass a list of all the integers you need to add:

This implementation works, but whenever you call this function you’ll also need to create a list of arguments to pass to it. This can be inconvenient, especially if you don’t know up front all the values that should go into the list.

This is where *args can be really useful, because it allows you to pass a varying number of positional arguments. Take the following example:

In this example, you’re no longer passing a list to my_sum() . Instead, you’re passing three different positional arguments. my_sum() takes all the parameters that are provided in the input and packs them all into a single iterable object named args .

Note that args is just a name. You’re not required to use the name args . You can choose any name that you prefer, such as integers :

The function still works, even if you pass the iterable object as integers instead of args . All that matters here is that you use the unpacking operator ( * ).

Bear in mind that the iterable object you’ll get using the unpacking operator * is not a list but a tuple . A tuple is similar to a list in that they both support slicing and iteration. However, tuples are very different in at least one aspect: lists are mutable, while tuples are not. To test this, run the following code. This script tries to change a value of a list:

The value located at the very first index of the list should be updated to 9 . If you execute this script, you will see that the list indeed gets modified:

The first value is no longer 0 , but the updated value 9 . Now, try to do the same with a tuple:

Here, you see the same values, except they’re held together as a tuple. If you try to execute this script, you will see that the Python interpreter returns an error:

This is because a tuple is an immutable object, and its values cannot be changed after assignment. Keep this in mind when you’re working with tuples and *args .

Using the Python kwargs Variable in Function Definitions

Okay, now you’ve understood what *args is for, but what about **kwargs ? **kwargs works just like *args , but instead of accepting positional arguments it accepts keyword (or named) arguments. Take the following example:

When you execute the script above, concatenate() will iterate through the Python kwargs dictionary and concatenate all the values it finds:

Like args , kwargs is just a name that can be changed to whatever you want. Again, what is important here is the use of the unpacking operator ( ** ).

So, the previous example could be written like this:

Note that in the example above the iterable object is a standard dict . If you iterate over the dictionary and want to return its values, like in the example shown, then you must use .values() .

In fact, if you forget to use this method, you will find yourself iterating through the keys of your Python kwargs dictionary instead, like in the following example:

Now, if you try to execute this example, you’ll notice the following output:

As you can see, if you don’t specify .values() , your function will iterate over the keys of your Python kwargs dictionary, returning the wrong result.

Ordering Arguments in a Function

Now that you have learned what *args and **kwargs are for, you are ready to start writing functions that take a varying number of input arguments. But what if you want to create a function that takes a changeable number of both positional and named arguments?

In this case, you have to bear in mind that order counts. Just as non-default arguments have to precede default arguments, so *args must come before **kwargs .

To recap, the correct order for your parameters is:

  1. Standard arguments
  2. *args arguments
  3. **kwargs arguments

For example, this function definition is correct:

The *args variable is appropriately listed before **kwargs . But what if you try to modify the order of the arguments? For example, consider the following function:

Now, **kwargs comes before *args in the function definition. If you try to run this example, you’ll receive an error from the interpreter:

In this case, since *args comes after **kwargs , the Python interpreter throws a SyntaxError .

Unpacking With the Asterisk Operators: * & **

You are now able to use *args and **kwargs to define Python functions that take a varying number of input arguments. Let’s go a little deeper to understand something more about the unpacking operators.

The single and double asterisk unpacking operators were introduced in Python 2. As of the 3.5 release, they have become even more powerful, thanks to PEP 448. In short, the unpacking operators are operators that unpack the values from iterable objects in Python. The single asterisk operator * can be used on any iterable that Python provides, while the double asterisk operator ** can only be used on dictionaries.

Let’s start with an example:

This code defines a list and then prints it to the standard output:

Note how the list is printed, along with the corresponding brackets and commas.

Now, try to prepend the unpacking operator * to the name of your list:

Here, the * operator tells print() to unpack the list first.

In this case, the output is no longer the list itself, but rather the content of the list:

Can you see the difference between this execution and the one from print_list.py ? Instead of a list, print() has taken three separate arguments as the input.

Another thing you’ll notice is that in print_unpacked_list.py , you used the unpacking operator * to call a function, instead of in a function definition. In this case, print() takes all the items of a list as though they were single arguments.

You can also use this method to call your own functions, but if your function requires a specific number of arguments, then the iterable you unpack must have the same number of arguments.

To test this behavior, consider this script:

Here, my_sum() explicitly states that a , b , and c are required arguments.

If you run this script, you’ll get the sum of the three numbers in my_list :

The 3 elements in my_list match up perfectly with the required arguments in my_sum() .

Now look at the following script, where my_list has 4 arguments instead of 3:

In this example, my_sum() still expects just three arguments, but the * operator gets 4 items from the list. If you try to execute this script, you’ll see that the Python interpreter is unable to run it:

When you use the * operator to unpack a list and pass arguments to a function, it’s exactly as though you’re passing every single argument alone. This means that you can use multiple unpacking operators to get values from several lists and pass them all to a single function.

To test this behavior, consider the following example:

If you run this example, all three lists are unpacked. Each individual item is passed to my_sum() , resulting in the following output:

There are other convenient uses of the unpacking operator. For example, say you need to split a list into three different parts. The output should show the first value, the last value, and all the values in between. With the unpacking operator, you can do this in just one line of code:

In this example, my_list contains 6 items. The first variable is assigned to a , the last to c , and all other values are packed into a new list b . If you run the script, print() will show you that your three variables have the values you would expect:

Another interesting thing you can do with the unpacking operator * is to split the items of any iterable object. This could be very useful if you need to merge two lists, for instance:

The unpacking operator * is prepended to both my_first_list and my_second_list .

If you run this script, you’ll see that the result is a merged list:

You can even merge two different dictionaries by using the unpacking operator ** :

Here, the iterables to merge are my_first_dict and my_second_dict .

Executing this code outputs a merged dictionary:

Remember that the * operator works on any iterable object. It can also be used to unpack a string:

In Python, strings are iterable objects, so * will unpack it and place all individual values in a list a :

The previous example seems great, but when you work with these operators it’s important to keep in mind the seventh rule of The Zen of Python by Tim Peters: Readability counts.

To see why, consider the following example:

There’s the unpacking operator * , followed by a variable, a comma, and an assignment. That’s a lot packed into one line! In fact, this code is no different from the previous example. It just takes the string RealPython and assigns all the items to the new list a , thanks to the unpacking operator * .

The comma after the a does the trick. When you use the unpacking operator with variable assignment, Python requires that your resulting variable is either a list or a tuple. With the trailing comma, you have defined a tuple with only one named variable, a , which is the list [‘R’, ‘e’, ‘a’, ‘l’, ‘P’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’] .

Where's the tuple? Show/Hide

You never get to see the tuple that Python creates in this operation, because you use tuple unpacking in combination with the unpacking operator * .

If you name a second variable on the left-hand side of the assignment, Python will assign the last character of the string to the second variable, while collecting all remaining characters in the list a :

When you use this operation with a second named variable like shown above, the results might be more familiar, if you’ve worked with tuple unpacking before. However, if you want to unpack all items of the variable-length iterable into a single variable, a , then you need to add the comma ( , ) without naming a second variable. Python will then unpack all items into the first named variable, which is a list.

While this is a neat trick, many Pythonistas would not consider this code to be very readable. As such, it’s best to use these kinds of constructions sparingly.

Conclusion

You are now able to use *args and **kwargs to accept a changeable number of arguments in your functions. You have also learned something more about the unpacking operators.

  • What *args and **kwargs actually mean
  • How to use *args and **kwargs in function definitions
  • How to use a single asterisk ( * ) to unpack iterables
  • How to use two asterisks ( ** ) to unpack dictionaries

If you still have questions, don’t hesitate to reach out in the comments section below! To learn more about the use of the asterisks in Python, have a look at Trey Hunner’s article on the subject.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Python args and kwargs: Demystified

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Davide Mastromatteo

Developer and editor of “the Python Corner". Blood donor, Apple user, Python and Swift addicted. NFL, Rugby and Chess lover. Constantly hungry and foolish.

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Aldren Santos

Geir Arne Hjelle

Jaya Zhané

Mike Driscoll

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

What Do You Think?

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal. Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Что такое args и kwargs в python

In this article, we will cover what ** (double star/asterisk) and * (star/asterisk) do for parameters in Python, Here, we will also cover args and kwargs examples in Python. We can pass a variable number of arguments to a function using special symbols.

There are two special symbols:

*args and **kwargs in Python

*args and **kwargs in Python

Special Symbols Used for passing arguments in Python:

  • *args (Non-Keyword Arguments)
  • **kwargs (Keyword Arguments)

Note: “We use the “wildcard” or “*” notation like this – *args OR **kwargs – as our function’s argument when we have doubts about the number of arguments we should pass in a function.”

What is Python *args?

The special syntax *args in function definitions in Python is used to pass a variable number of arguments to a function. It is used to pass a non-keyworded, variable-length argument list.

  • The syntax is to use the symbol * to take in a variable number of arguments; by convention, it is often used with the word args.
  • What *args allows you to do is take in more arguments than the number of formal arguments that you previously defined. With *args, any number of extra arguments can be tacked on to your current formal parameters (including zero extra arguments).
  • For example, we want to make a multiply function that takes any number of arguments and is able to multiply them all together. It can be done using *args.
  • Using the *, the variable that we associate with the * becomes iterable meaning you can do things like iterate over it, run some higher-order functions such as map and filter, etc.

Example 1:

Python program to illustrate *args for a variable number of arguments

python3

Output:

Example 2:

Python program to illustrate *args with a first extra argument

Python3

Output:

What is Python **kwargs?

The special syntax **kwargs in function definitions in Python is used to pass a keyworded, variable-length argument list. We use the name kwargs with the double star. The reason is that the double star allows us to pass through keyword arguments (and any number of them).

  • A keyword argument is where you provide a name to the variable as you pass it into the function.
  • One can think of the kwargs as being a dictionary that maps each keyword to the value that we pass alongside it. That is why when we iterate over the kwargs there doesn’t seem to be any order in which they were printed out.

Example 1:

Python program to illustrate *kwargs for a variable number of keyword arguments. Here **kwargs accept keyworded variable-length argument passed by the function call. for first=’Geeks’ first is key and ‘Geeks’ is a value. in simple words, what we assign is value, and to whom we assign is key.

Что такое *args и **kwargs в Python?

Дмитрий ПереводIT

Функции — жизнь, не так ли? Не важно, новичок вы в программировании в целом или пришли из другого языка: осваивая Python, вы узнаете, что число параметров, указанных в определении функции, совпадает с числом передаваемых аргументов.

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

Не позволяйте синтаксису вас напугать. Это никакие не особые параметры. Они вообще не особо вычурны, и мы сейчас научимся их правильно использовать.

Позиционные аргументы против именованных

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

Все три аргумента необходимы. Упущение любого из них вызовет ошибку.

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

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

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

Оператор *

Позвольте мне начать с упоминания о том, как мне нравится этот оператор. Он такой… визуальный. Значок * больше всего ассоциируется с умножением, но в Python он делает то же самое, что spread ( . ) в JS.

Я могу описать его как оператор расширения, распаковывающий наборы домино, чтобы потом выстроить из них одну единую огромную последовательность. Однако звездочка представляет еще более мощную аналогию. Вот простой пример:

В этом примере мы берем содержимое a и распаковываем его в новый список b .

Как использовать *args и **kwargs

Итак, нам известно, что оператор * распаковывает множественные значения и существует два типа параметров функции. Если вы до сих пор не догадались, то *args — это сокращение от arguments (аргументы), а **kwargs — это сокращение от keyword arguments (именованные аргументы).

Каждый из них используется для распаковки соответствующих им типов аргументов, определенных вызовами функции, согласно списку аргументов переменной длины.

Например, давайте создадим функцию для печати баллов для тестирования студента:

Так, подождите. Я не использовал имя *args ? Все верно, “args” является стандартным обозначением, но при этом только лишь именем. Главная роль здесь кроется именно за единичной звездочкой, которая создает список, где содержимое является позиционными аргументами, которые изначально определяются вызовом функции.

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

Заключение

Немного мудрых слов в напутствие вам для избежания распространенных ошибок и расширения знаний:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *