Использование произвольного набора именованных аргументов

We use cookies. Read the Privacy and Cookie Policy

Иногда программа должна получать произвольное количество аргументов, но вы не знаете заранее, какая информация будет передаваться функции. В таких случаях можно написать функцию, получающую столько пар «ключ—значение», сколько указано в команде вызова. Один из возможных примеров — построение пользовательских профилей: вы знаете, что вы получите информацию о пользователе, но не знаете заранее, какую именно. Функция build_profile() в следующем примере всегда получает имя и фамилию, но также может получать произвольное количество именованных аргументов:

user_profile.py

def build_profile(first, last, **user_info):

. ."""Строит словарь с информацией о пользователе."""

. .profile = {}

(1) . .profile['first_name'] = first

. .profile['last_name'] = last

(2) . .for key, value in user_info.items():

. . . .profile[key] = value

. .return profile

user_profile = build_profile('albert', 'einstein',

. . . . . . . . . . . . . . location='princeton',

. . . . . . . . . . . . . . field='physics')

print(user_profile)

Определение build_profile() ожидает получить имя и фамилию пользователя, а также позволяет передать любое количество пар «имя—значение». Две звездочки перед параметром **user_info заставляют Python создать пустой словарь с именем user_info и упаковать в него все полученные пары «имя—значение». Внутри функции вы можете обращаться к парам «имя–значение» из user_info точно так же, как в любом словаре.

В теле build_profile() создается пустой словарь с именем profile для хранения профиля пользователя. В точке (1) в словарь добавляется имя и фамилия, потому что эти два значения всегда передаются пользователем. В точке (2) функция перебирает дополнительные пары «ключ—значение» в словаре user_info и добавляет каждую пару в словарь profile. Наконец, словарь profile возвращается в точку вызова функции.

Вызовем функцию build_profile() и передадим ей имя 'albert', фамилию 'einstein', и еще две пары «ключ—значение» location='princeton' и field='physics'. Программа сохраняет возвращенный словарь в user_profile и выводит его содержимое:

{'first_name': 'albert', 'last_name': 'einstein',

'location': 'princeton', 'field': 'physics'}

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

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

Упражнения

8-12. Сэндвичи: напишите функцию, которая получает список компонентов сэндвича. Функция должна иметь один параметр для любого количества значений, переданных при вызове функции, и выводить описание заказанного сэндвича. Вызовите функцию три раза с разными количествами аргументов.

8-13. Профиль: начните с копии программы user_profile.py. Создайте собственный профиль вызовом build_profile(), укажите имя, фамилию и три другие пары «ключ—значение» для вашего описания.

8-14. Автомобили: напишите функцию для сохранения информации об автомобиле в словаре. Функция всегда должна возвращать производителя и название модели, но при этом она может получать произвольное количество именованных аргументов. Вызовите функцию с передачей обязательной информации и еще двух пар «имя—значение» (например, цвет и комплектация). Ваша функция должна работать для вызовов следующего вида:

car = make_car(‘subaru’, ‘outback’, color=’blue’, tow_package=True)

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