Какие бывают параметры в функциях в python
Перейти к содержимому

Какие бывают параметры в функциях в python

  • автор:

Функции в Python

Функция — это блок кода, который выполняет определенную задачу. В Python есть два типа функции: встроенные и пользовательские. Параметр — это значение, которое принимает функция. Аргумент — это значение, которое передается в функцию при ее вызове в программе. Оператор return используется для возвращения значения из функции.

Что такое функция?

Функция — это блок кода, который выполняет определенную задачу.

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

функция создания круга;

функция раскрашивания круга.

Разделение сложной задачи на более мелкие части делает нашу программу простой для понимания и повторного использования.

Типы функций в Python

Есть два типа функций:

Функции из Стандартной библиотеки Python — это встроенные функции, доступные для использования.

Пользовательские функции — мы можем создавать собственные функции на основе наших требований.

Python — Function and Function Parameters

Analytics Vidhya

In a nutshell when we defined a function, we may or may not pass parameters. But most of the time parameters are passed while defining a function. Semantically we defined function as below:

So when we call the function,

In this context x and y are arguments of myfunction and most importantly note that x and y are passed by reference. i.e. the memory address of x and y are passed.
We can pass positional and keyword arguments to a function.

Positional and Keyword Arguments

We normally assign the arguments to parameters of a function in the order in which they are passed, i.e. the position of the parameter.

Let’s define a function, which takes two arguments and return the concatenation of two strings.

So when we call above function by passing arguments,

Where the first argument “hello” assigned to first parameter i.e. a and second argument “world!!”assigned to second parameter i.e. b.

We can make positional argument as optional by specifying a “Default” value for the corresponding parameter. Let’s modify our concatenate function by adding additional parameter,

We added third variable “c” with default value as “Welcome”. So if we call above function without passing third argument, then default value for third positional parameter will be referred.

So if we call the above function,

The output will be:

Now if we pass third argument then the function will not consider the default value of third parameter (which is obvious ��). To illustrate let’s modify our code :

When we run the above code, the output will be:

Hello, this is my first story in Medium

So far so good and pretty straightforward to understand. However, there might be a situation where we have function, in which any one of the parameter is optional. To be more precise, let’s say we have addition function which have three parameters and one of them or to simplify the second positional parameter is optional.

If we call this function by passing only two arguments, for example:

then python will not able to identify whether the second argument i.e. 150 refers to second parameter i.e. b or third parameter i.e. c. So it will throw error while executing.

The error could be something like:

So, in order to avoid such error, we need to follow following rule while passing positional parameter with default value.

If we defined a positional parameter with default value then for every positional parameter(s) after it we must also be given default value.

So we need to modify our addition function by assigning default value to third parameter i.e. c

Now when we run below code:

For the addition function , we can now pass one argument as well. For example:

Now what if you want to skip the second second argument and pass first and third arguments to addition function. We can achieve this by using “Keyword Arguments” which also known as “Named Arguments”.

Using Keyword or named arguments, we can invoke the function by passing 1st and 3rd arguments leaving default values for 2nd argument.

Notes:

1. We can specify positional arguments by using their parameter name, no matter they have assigned values or not.

Example: Let’s define a function which takes 4 parameters and return all 4 values passed to the function.

You can call the function either passing all the four arguments without using Keyword arguments or with keyword arguments.

val1 = 120, val2 =140, val3 =300, val4 =400

If we are using keyword arguments, then order of passing parameter does not matter and that is the advantage of using keyword arguments.

However there is a caveat when using Keyword argument.

2. If you started using keyword argument then all arguments thereafter must be keyword arguments.

When we run the above code, below error message will display:

Arbitrary Arguments (*args)

When we define a function with parameters and access the function with arguments then eventually we are accessing the parameters by their relative positions.

For example, my_returnargs function takes 3 positional arguments and returns these value.

Let’s define a list variable which has three values:

Now let’s pass list as an arguments to my_returnargs function, rather we will unpack list so that all the values will be passed as an argument:

The output will be

First Positional Value = Hello
Second Positional Value = World
Third Positional Value = Learn Python

In the above example we have 3 arguments passed in the function and since list has 3 elements so when unpacked all the three arguments assigned with value.

Now what if we have same list which has more than 3 elements and tries to unpack in function arguments then what will happen ?

So when we execute the above code, python will throw error:

We can avoid such error by passing arbitrary arguments (*args) in the function. We can modify the function to take two positional arguments and post that arbitrary arguments.

Now let’s run the same code where we have unpacked the list with 4 values

The output will be:

First Positional Value = Hello
Second Positional Value = World
Arbitrary Argument Values = (‘Learn Python’, ‘Some Extra Arguments’)

Note: The args argument returns the value as tuple

Also you can not add any positional argument after the *args. Which means *args eventually exhaust all the positional arguments.

We can define a function by passing a positional arguments after *args. Python will never complain about while defining such function 🙂

The problem will occur when we call the function by passing arguments and python will throw TypeError

However, we can get rid of such issue by enforcing user to pass mandatory keyword arguments.

Keyword Arguments *

The question will always crops that when can we use mandatory keyword arguments ? So the answer is, once we exhausts out of all the positional arguments.

To illustrate let’s see below example:

When we run the above code the out put will be:

First Positional Value = Hello
Second Positional Value = World
Arbitrary Argument Values = (‘Learn Python’, ‘Some Extra Arguments’)
Another positional argument Value = This is a keyword argument

We can restrict function explicitly not to pass any positional argument by passing * as parameter. For example:

If we try to pass positional argument along with Keyword argument then python will through TypeError

The Output will be:

But if we pass only Keyword argument then Python will not show any error

The Output will be:

Only Keyword Argument : Hello World!!

Now let’s combine positional arguments, optional positional arguments, *args, no positional argument and mandatory keyword arguments.

In the above function, we have :

· Mandatory Positional parameter i.e. val1

· Optional Positional parameter i.e. val2

· Optional arbitrary number of positional arguments i.e. *args

· Mandatory Keyword Parameter i.e. val3

· Finally optional positional parameter i.e. val4

So when we call the function:

And the output will be:

val1 = 101
val2 = Python
args = (‘Hello’, ‘Welcome’, 20, 30)
val3 = This is a mandatory keyword arguments after args
val4 = Hello World.

What if we restrict no positional arguments followed by mandatory keyword arguments and then optional positional argument within a function.

Let’s modify the same function as below:

In the above function, we have :

· Mandatory Positional parameter i.e. val1

· Optional Positional parameter i.e. val2

· No positional arguments i.e. *

· Mandatory Keyword Parameter i.e. val3

· Finally optional positional parameter i.e. val4

So when we call the function by passing three positional arguments followed by keyword arguments

then we will encounter below error:

The reason is the first two arguments refer to positional arguments i.e. val1 and val2 (though val2 is optional positional argument which has default value of 50 but here we pass 25.) . However when we pass the third argument i.e. 1000 before keyword argument i.e. val3 then the Python could not process as the function is defined as after the two positional arguments there should not be any positional arguments to be passed rather mandatory keyword argument i.e. val3 and followed by another optional positional parameter.

Let’s modify the arguments while calling the function as below:

val1 = test
val2 = 25
val3 = 100.1005
val4 = Welcome to pythonic way of writing python

Quite interesting but very important (more specifically it’s a caveat ), if you call a function with named or keyword arguments though you declare these as positional argument followed by *args then Python will throw Syntax error stating Positional argument follows keyword argument.

To illustrate this , let’s run below code:

So when we run the above code, below error will display:

What if we call the function and tries to pass the option argument at end of *args. Well certainly Python will throw error as it finds multiple values of positional argument val3.

Arbitrary number of keyword arguments (**kwargs)

In python we can add arbitrary number of keyword arguments to a function using **kwargs.

User can specify **kwargs even though the positional arguments are not exhausted (which is not true for *args). However, there should not be any positional parameters that can come after **kwargs.

But there is a caveat to **kwargs. If we declare a function where the first parameter is * i.e. no positional arguments followed by **kwargs then Python will not process rather throws a syntax error:

However, the above function will work if we pass mandatory keyword or optional positional argument followed by **kwargs.

Note: The kwargs argument returns the value as dictionary

Большая история аргументов функций в Python

Ну, на самом деле, история аргументов в Python не такая уж и большая.

Я всегда удивлялся тому, что для работы с аргументами Python-функций достаточно лишь разобраться с *args и **kwargs . И удивлялся я не зря. Как оказалось, аргументы — это далеко не так просто. В этом материале я хочу дать общий обзор всего того, что связано с аргументами функций в Python. Надеюсь, что в итоге у меня, и правда, получится показать общую картину работы с аргументами, и что эта статья не станет очередной публикацией, в которой читателю не удастся найти ничего нового. А теперь — к делу.

Большинству читателей этой статьи, полагаю, понятна сущность аргументов функций. Для начинающих поясню, что это — объекты, отправляемые функции инициатором её вызова. При передаче аргументов функции выполняется множество действий, зависящих от того, объекты какого типа отправляют функции (изменяемые или неизменяемые объекты). Инициатор вызова функции — это сущность, которая вызывает функцию и передаёт ей аргументы. Говоря о вызове функций, стоит поразмыслить над некоторыми вещами, которые мы сейчас обсудим.

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

Как видно, вызов функции никак не повлиял на переменную a . Именно это происходит в том случае, если функции передаётся неизменяемый объект.

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

Заметили ли вы тут что-то новое? Если вы ответите «Нет», то будете правы. Но если как-то повлиять на элементы изменяемого объекта, переданного функции, мы станем свидетелями кое-чего другого.

Как видите, объект из параметра lst был изменён после вызова функции. Произошло это из-за того, что мы работаем со ссылкой на объект, хранящейся в параметре lst . В результате изменение содержимого этого объекта выходит за пределы функции. Избежать этого можно, просто выполняя глубокие копии подобных объектов и записывая их в локальные переменные функции.

Это вас ещё не удивило? Если нет — тогда хотелось бы мне сделать так, чтобы вы, пропустив то, что вам известно, сразу же перешли к новому для вас материалу. А если да — то, помяните мои слова, вы, ближе знакомясь с аргументами, узнаете ещё много интересного.

Итак, вот что следует знать об аргументах функций:

  1. Порядок передачи функциям позиционных аргументов.
  2. Порядок передачи функциям именованных аргументов.
  3. Назначение значений аргументов, применяемых по умолчанию.
  4. Организация обработки наборов аргументов переменной длины.
  5. Распаковка аргументов.
  6. Использование аргументов, которые можно передавать только по имени (keyword-only).

1. Порядок передачи функциям позиционных аргументов

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

Переменные a , b и c имеют, соответственно, значения 1, 2 и 3. Эти переменные играют роль аргументов, с которыми вызывается функция foo . Они, при первом вызове функции, соответствуют параметрам d , e и f . Этот механизм применим практически во всех из вышеперечисленных выше 6 пунктов, касающихся того, что нужно знать об аргументах функций в Python. Место размещения позиционного аргумента, передаваемого функции при вызове, играет главную роль при назначении значений параметрам функции.

2. Порядок передачи функциям именованных аргументов

Именованные аргументы передают функциям с указанием имён этих аргументов, соответствующих тем именам, которые им назначены при объявлении функции.

Как видите, функция foo принимает 3 аргумента. Эти аргументы имеют имена arg1 , arg2 и arg3 . Обратите внимание на то, как мы, при вызове функции, меняем позиции аргументов. Именованные аргументы обрабатываются не так, как позиционные, хотя система продолжает читать их слева направо. Python, при назначении соответствующих значений параметрам функций, учитывает имена аргументов, а не их позиции. В результате оказывается, что функция выводит одно и то же независимо от позиций переданных ей аргументов. Это — всегда 1 2 3 .

Обратите внимание на то, что здесь продолжают действовать механизмы, описанные в пункте №1.

3. Назначение значений аргументов, применяемых по умолчанию

Именованным аргументам можно назначать значения, применяемые по умолчанию. При использовании этого механизма в функции определённые аргументы становятся необязательными. Объявление подобных функций выглядит как то, что мы рассматривали в пункте №2. Единственное различие заключается в том, как именно вызываются эти функции.

Обратите внимание на то, что в этом примере мы не передаём функции все аргументы, описанные при её объявлении. В этих случаях соответствующим параметрам назначаются значения, заданные по умолчанию. Продолжим этот пример:

Это — простые и понятные примеры использования вышеописанных механизмов вызова функций с передачей ей именованных аргументов. А теперь давайте усложним наши эксперименты, объединив то, о чём мы до сих пор говорили в пунктах №1, №2 и №3:

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

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

Вы можете воспринимать это как правило. Позиционные аргументы не должны следовать за именованными аргументами при вызове функции.

4. Организация обработки наборов аргументов переменной длины

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

Этот код доказывает то, что в параметре args хранится кортеж, содержащий то, что передано функции при её вызове.

В вышеприведённом коде показано то, что в параметре kwargs хранится словарь, состоящий из пар ключ-значение и представляющий именованные аргументы, переданные функции при вызове.

Но надо отметить, что функции, рассчитанной на приём позиционных аргументов, нельзя передавать именованные аргументы (и наоборот).

А теперь давайте соберём вместе всё то, что мы разобрали в пунктах №1, №2, №3 и №4, и со всем этим поэкспериментируем, исследовав разные комбинации аргументов, которые можно передавать функциям при их вызове.

Как видите, в нашем распоряжении оказывается кортеж args и словарь kwargs .

А вот — ещё одно правило. Оно заключается в том, что конструкцию *args нельзя использовать после конструкции **kwargs .

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

При объявлении функций можно комбинировать позиционные аргументы, *args и *kwagrs следующим образом:

При объявлении функции foo мы исходили из того, что у неё должен быть один обязательный позиционный аргумент. За ним следует набор позиционных аргументов переменной длины, а за этим набором идёт набор именованных аргументов переменной длины. Зная это, мы легко сможем «расшифровать» каждый из вышеприведённых вызовов функции.

В Вызове 1 функции переданы аргументы 1 и a=1 . Это, соответственно, позиционный и именованный аргументы. Вызов 2 — это разновидность Вызова 1 . Здесь длина набора позиционных аргументов равна нулю.

В Вызове 3 мы передаём функции 1 , 2 и a=1,b=2 . Это значит, что она теперь принимает два позиционных аргумента и два именованных аргумента. В соответствии с объявлением функции оказывается, что 1 воспринимается как обязательный позиционный аргумент, 2 идёт в набор позиционных аргументов переменной длины, а a=1 и b=2 попадают в набор именованных аргументов переменной длины.

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

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

Вызовы этой функции можно «расшифровать» так же, как это делалось при анализе предыдущей функции.

При вызове этой функции ей надо передавать, как минимум, один позиционный аргумент. Иначе мы столкнёмся с ошибкой:

Обратите внимание на то, что вызов foo(1) работает нормально. Дело тут в том, что в том случае, если функцию вызывают, не указывая значение для именованного аргумента, значение ему назначается автоматически.

А вот ещё некоторые ошибки, с которыми можно столкнуться при неправильном вызове этой функции:

Обратите особое внимание на ошибку, возникающую при выполнении Вызова 3 .

5. Распаковка аргументов

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

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

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

Экспериментируя с распаковкой аргументов, можно столкнуться с новой ошибкой:

Эта ошибка возникает из-за конфликта именованного аргумента, b=5 , и позиционного аргумента. Как мы выяснили в разделе №2, при передаче именованных аргументов их порядок значения не имеет. В результате в обоих случаях возникает одна и та же ошибка.

6. Использование аргументов, которые можно передавать только по имени (keyword-only)

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

Как видите, ожидается, что функции обязательно будет передан именованный аргумент b , который, в объявлении функции, указан после *args . При этом в объявлении функции можно использовать просто символ * , после которого, через запятую, идут идентификаторы именованных аргументов, которые можно передавать функции только по имени. Такая функция не будет рассчитана на приём набора позиционных аргументов переменной длины.

Функция, объявленная в предыдущем примере, принимает один позиционный аргумент и два именованных аргумента, которые можно передавать только по имени. Это приводит к тому, что для правильного вызова функции ей необходимо передавать оба именованных аргумента. После * можно описывать и именованные аргументы, которым заданы значения, применяемые по умолчанию. Это даёт нам определённую свободу при вызове подобных функций.

Обратите внимание на то, что функцию можно нормально вызывать, не передавая ей аргументы b и d , так как для них заданы значения, применяемые по умолчанию.

Итоги

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

Узнали ли вы из этого материала что-то новое об аргументах функций в Python?

Типы параметров функции#

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

обязательными параметрами

необязательными параметрами (опциональными, параметрами со значением по умолчанию)

Обязательные параметры#

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

Функция с обязательными параметрами (файл func_params_types.py):

Функция check_passwd ожидает два аргумента: username и password.

Функция проверяет пароль и возвращает False, если проверки не прошли и True, если пароль прошел проверки:

Необязательные параметры (параметры со значением по умолчанию)#

При создании функции можно указывать значение по умолчанию для параметра таким образом: def check_passwd(username, password, min_length=8) . В этом случае, параметр min_length указан со значением по умолчанию и может не передаваться при вызове функции.

Пример функции check_passwd с параметром со значением по умолчанию (файл func_check_passwd_optional_param.py):

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

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

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