Python call function args kwargs

Python args And kwargs Explained: All You Need to Know

Using args and kwargs can be quite cryptic especially if you are new to Python. Let’s find out together all you need to know about them.

*args and **kwargs allow to pass an arbitrary number of positional arguments (*args) and keyword arguments (**kwargs) to a Python function. You can use *args and **kwargs to make your Python code more flexible.

We will start with a simple example that will show you quickly how to use *args and **kwargs. Then we will got through more examples to make sure you have a full understanding of them.

We will also see where else you can use *args and **kwargs…

An Example of How to Use *args With a Function

Let’s create a simple function that calculates the sum of two numbers:

def sum(x, y): result = x + y return result

Then we will call it with one, two or three arguments to see what happens:

One argument

We get back the following error because the sum function expects two arguments and we have only passed one:

Traceback (most recent call last): File "/opt/python/codefather/args_kwargs.py", line 25, in print(sum(1)) TypeError: sum() missing 1 required positional argument: 'y'

Notice how the Python interpreter is telling us that 1 required positional argument (y) is missing.

You will see soon how positional arguments are related to *args

Two arguments

This time there is no error. Our program prints the correct sum because we pass the correct number of arguments when we call the sum function.

Thee arguments

We get back an error because our function doesn’t know how to handle three arguments:

Traceback (most recent call last): File "/opt/python/codefather/args_kwargs.py", line 25, in print(sum(1, 2, 3)) TypeError: sum() takes 2 positional arguments but 3 were given

We can solve this problem with *args…

*args allows to pass a variable number of positional arguments to a Python function. It’s accessible as tuple in the function itself.

Let’s make few changes to our sum function:

  • Add *args as last argument in the signature of the function.
  • Check if args is empty and if it’s not empty add every argument in *args to the final result.
def sum(x, y, *args): print("args value:", args) result = x + y if args: for arg in args: result += arg return result

When we execute this code we get 6 as result and we can also see the content of the *args tuple:

>>> print(sum(1, 2, 3)) args value: (3,) 6

Tuples are similar to Python lists with the only difference that they are immutable.

Python args And kwargs Explained

This means that arg1 has to go before *args.

Let’s see if it’s true, here is the updated function. Notice how I have also changed the position of the argument 6 in the call to the function:

def print_args_type(arg1, *args, **kwargs): print("arg1:", arg1) print("*args:", args) print("**kwargs:", kwargs) print_args_type(6, 1, 3, number=5)

Python assigns the number 6 to arg1, the remaining two positional arguments (1 and 3) to *args and the only keyword argument to **kwargs.

Читайте также:  Css отображать поверх всего

Let’s add also a fixed keyword argument that as explained before has to go between *args and **kwargs in the function signature:

def print_args_type(arg1, *args, kw_arg1, **kwargs): print("arg1:", arg1) print("*args:", args) print("kw_arg1:", kw_arg1) print("**kwargs:", kwargs) print_args_type(6, 1, 3, kw_arg1=4, number=5)

And the output matches what we expect:

arg1: 6 *args: (1, 3) kw_arg1: 4 **kwargs:

Python Unpacking Operators Explained

At some point in this tutorial I have mentioned that * and ** are unpacking operators.

But, what does it mean in practice?

Let’s start by printing the value of a tuple without and with the * operator:

args = (1, 2, 3) print(args) print(*args)

So, without the unpacking operator we see that the full tuple gets printed…

…when we apply the unpacking operator * the elements of the tuple are “unpacked”. The print statement prints three individual numbers.

This means that each one of the three numbers is a separate argument for the print() function when we apply the * operator.

The * unpacking operator applies to iterables (e.g. tuples and list).

Now, let’s have a look at what happens when we apply the * operator to a dictionary:

args = print(args) print(*args)

We only get back the keys of the dictionary back when we apply the * operator, this is not really what we want.

To unpack dictionaries you should use the ** operator.

Here is an example of how to use the ** operator to create a new dictionary that contains all the key / value pairs from two dictionaries:

The resulting Python dictionary is:

Now you know how unpacking operators can help you in your Python programs.

Using *args With a Python Lambda Function

Let’s go back to our initial sum function:

def sum(x, y): result = x + y return result

Below you can see the lambda representation of this function:

>>> lambda x,y : x+y at 0x101dab680> 

And here is how you can pass two arguments to this lambda:

Now, let’s say we want to pass an arbitrary number of arguments to our lambda function

>>> (lambda *args: sum(args))(1,2,4,5,6) 18 >>> (lambda *args: sum(args))(3,7,6) 16 

I have written a full article about Python lambdas if you are interested in learning how to use them.

One last thing you can use *args and **kwargs for…

Args and Kwargs as Part of a Decorator

*args and **kwargs are also very useful to define decorators in Python.

You can use them in the definition of a wrapper function inside your decorator, with the aim of passing through any arguments to the function that is decorated.

Here is an example of code:

def verify_user(func): def wrapper(*args, **kwargs): if not user['logged_in']: print("ERROR: User <> is not logged in!".format(user['name'])) return else: print("INFO: User <> is logged in".format(user['name'])) return func(*args, **kwargs) return wrapper

I have created an article about Python decorators if you want to learn how decorators wok and how to use *args and **kwargs as part of decorators.

Conclusion

We have learned together how you can pass a variable number of arguments to Python functions using *args and **kwargs.

Читайте также:  Java ljava lang object cannot be cast to ljava lang integer

To recap what we have covered:

  • *args allows to pass a variable number of positional arguments to a function. This is a tuple that contains the arguments in the order in which they are passed in the function call.
  • **kwargs allows to pass a variable number of keyword arguments to a function. This is a dictionary, that’s why we talk about keyword arguments. Because arguments are identified by a key.

What matters in the name of these parameters are the * and the **. The actual names args and kwargs are not enforced by the Python interpreter and can be replaced with anything you want.

The main point of using *args and **kwargs is creating flexible functions that can adapt to multiple use cases.

Consider, for example, a function that calculates the sum of two numbers as opposed as the sum of any numbers. And this concept can be extended to anything you want to do with your Python code.

  • looked at the order expected by the Python interpreter for positional and keyword arguments.
  • practiced the use of the unpacking operators * and **.

And now it’s time for you to start using *args and **kwargs…

…if you have any questions please let me know in the comments below.

I’m a Software Engineer and Programming Coach. I want to help you in your journey to become a Super Developer!

Источник

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

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

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

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

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

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

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

def printThese(a,b,c): print(a, "is stored in a") print(b, "is stored in b") print(c, "is stored in c") printThese(1,2,3) """ 1 is stored in a 2 is stored in b 3 is stored in c """

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

def printThese(a,b,c): print(a, "is stored in a") print(b, "is stored in b") print(c, "is stored in c") printThese(1,2) """ TypeError: printThese() missing 1 required positional argument: 'c' """

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

def printThese(a,b,c=None): print(a, "is stored in a") print(b, "is stored in b") print(c, "is stored in c") printThese(1,2) """ 1 is stored in a 2 is stored in b None is stored in c """

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

Читайте также:  Python get all keys in dict python

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

def printThese(a=None,b=None,c=None): print(a, "is stored in a") print(b, "is stored in b") print(c, "is stored in c") printThese(c=3, a=1) """ 1 is stored in a None is stored in b 3 is stored in c """

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

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

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

a = [1,2,3] b = [*a,4,5,6] print(b) # [1,2,3,4,5,6]

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

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

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

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

def printScores(student, *scores): print(f"Student Name: ") for score in scores: print(score) printScores("Jonathan",100, 95, 88, 92, 99) """ Student Name: Jonathan 100 95 88 92 99 """

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

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

def printPetNames(owner, **pets): print(f"Owner Name: ") for pet,name in pets.items(): print(f": ") printPetNames("Jonathan", dog="Brock", fish=["Larry", "Curly", "Moe"], turtle="Shelldon") """ Owner Name: Jonathan dog: Brock fish: ['Larry', 'Curly', 'Moe'] turtle: Shelldon """

Итоги

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

  • Используйте общепринятые конструкции *args и **kwargs для захвата позиционных и именованных аргументов.
  • Конструкцию **kwarg s нельзя располагать до *args . Если это сделать — будет выдано сообщение об ошибке.
  • Остерегайтесь конфликтов между именованными параметрами и **kwargs , в случаях, когда значение планируется передать как **kwarg -аргумент, но имя ключа этого значения совпадает с именем именованного параметра.
  • Оператор * можно использовать не только в объявлениях функций, но и при их вызове.

Источник

Оцените статью