Курс по Python: https://stepik.org/course/100707
На этом занятии узнаем, как функциям можно
передавать произвольное число аргументов. Где это используется, я думаю, вы
понимаете? Например, известная нам функция
может принимать
разное число аргументов и возвращает максимальное значение. Как можно самим
определять такие функции? Делается это очень просто. Допустим, мы с вами хотим
задать функцию для формирования маршрута к файлу:
F:\~stepik.org\Добрый, добрый Python (Питон)\39\p39. Функции.docx
И этот маршрут
может состоять из нескольких частей. Причем, число фрагментов может быть
произвольным. Опишем такую функцию. Я назову ее os_path(), а вместо
списка параметров запишу звездочку и одну переменную args:
def os_path(*args):
print(args)
Для начала,
посмотрим, как это будет работать. Вызовем функцию с тремя строковыми
аргументами:
os_path("F:\\~stepik.org", "Добрый, добрый Python (Питон)", "39\\p39. Функции.docx")
Не забываем
здесь про экранирование обратных слешей. Выполним эту программу и в консоли
видим, что переменная args ссылается на кортеж со значениями
переданных трех аргументов. Здорово, да?! Чтобы функция принимала произвольное
число аргументов, в ее объявлении достаточно у параметра прописать оператор *.
Это оператор упаковки аргументов в кортеж и через переменную args мы сможем с ним
работать.
Давайте теперь
довершим нашу функцию и сформируем полный путь на основе его фрагментов.
Сделать это можно с помощью знакомого нам метода join(), следующим
образом:
def os_path(*args):
path = "\\".join(args)
return path
И, далее,
вызвать эту функцию:
p = os_path("F:\\~stepik.org", "Добрый, добрый Python (Питон)", "39\\p39. Функции.docx")
print(p)
Надеюсь, из
этого примера, вам понятно, как объявлять функцию с произвольным числом фактических
параметров. Хорошо, а что если мы передадим этой функции дополнительно один
именованный аргумент:
p = os_path("F:\\~stepik.org",
"Добрый, добрый Python (Питон)",
"39\\p39. Функции.docx",
sep='/'
)
При запуске
программы увидим ошибку, что функция не имеет такого формального параметра. Дело
в том, что записывая объявление *args мы определяем лишь произвольное число фактических
параметров, но не формальных. Как это можно поправить? Здесь есть, по крайней
мере, два способа. В самом простом варианте, достаточно прописать этот
формальный параметр в объявлении функции:
def os_path(*args, sep='\\'):
path = sep.join(args)
return path
И теперь никаких
проблем с вызовом нет. Но, конечно, указать, какой-либо другой именованный
аргумент мы не можем:
p = os_path("F:\\~stepik.org",
"Добрый, добрый Python (Питон)",
"39\\p39. Функции.docx",
sep='/', trim=True
)
Снова получим ту
же самую ошибку. Так как же определить в функции произвольное число формальных
параметров? Делается это с помощью следующего синтаксиса:
def os_path(*args, **kwargs):
print(kwargs)
path = kwargs['sep'].join(args)
return path
Мы прописываем
уже две звездочки, а затем, имя переменной, которая будет ссылаться на
упакованные значения в виде словаря. Убедимся в этом, выполним программу и
смотрите, в консоли коллекция kwargs действительно представляет собой
словарь, ключами которого являются имена аргументов, а значениями – значения
аргументов. Все очень удобно и просто, как всегда в Python!
Причем,
коллекция **kwargs обязательно
должна быть записана после коллекции *args, наоборот
нельзя, так как вначале должны идти фактические параметры и только потом –
формальные. Мало того, мы можем некоторые параметры указывать явно, например:
def os_path(*args, sep='\\', **kwargs):
path = sep.join(args)
return path
И, тем самым,
гарантировать их существование внутри функции. А другие, передаваемые
именованные аргументы, следует проверять, прежде чем использовать, например,
для параметра trim сначала делаем
проверку его существования в словаре kwargs, а затем,
смотрим, чему равно это значение:
def os_path(*args, sep='\\', **kwargs):
if 'trim' in kwargs and kwargs['trim']:
args = [x.strip() for x in args]
path = sep.join(args)
return path
Если условие
выполняется, то удаляем пробелы до и после фрагментов путей к файлу.
То же самое и с
фактическими параметрами. Некоторые из них можно явно указать, при объявлении
функции:
def os_path(disk, *args, sep='\\', **kwargs):
args = (disk,) + args
if 'trim' in kwargs and kwargs['trim']:
args = [x.strip() for x in args]
path = sep.join(args)
return path
И тогда на
первый аргумент будет ссылаться параметр disk, а остальные
позиционные аргументы упаковываться в коллекцию args:
p = os_path("F:", "~stepik.org",
"Добрый, добрый Python (Питон)",
"39\\p39. Функции.docx",
sep='/', trim=True
)
Вот принцип, по
которому объявляются функции с произвольным числом фактических и формальных
параметров.
Вам осталось
закрепить этот материал практическими заданиями и жду всех вас на следующем
уроке.
Курс по Python: https://stepik.org/course/100707