Введение
В этой лабораторной работе мы рассмотрим, как определять и использовать функции с параметрами в Python. Функции становятся гораздо более мощными, когда они могут принимать входные данные, что делает их динамичными и многократно используемыми.
Мы рассмотрим несколько типов параметров функций, включая позиционные параметры, значения по умолчанию, именованные аргументы (keyword arguments) и аргументы переменной длины. С помощью практических примеров вы научитесь создавать гибкие функции, способные обрабатывать разнообразные входные данные.
Определение функций с позиционными параметрами
Параметры позволяют передавать данные в функцию, делая её поведение адаптируемым в зависимости от полученного ввода. Начнем с наиболее распространенного типа: позиционных параметров. Аргументы, передаваемые функции, присваиваются этим параметрам на основе их порядка.
Сначала найдите файл positional_params.py в проводнике файлов слева в WebIDE и откройте его.
Теперь определим функцию с именем hello, которая принимает один параметр, name. Добавьте следующий код в файл positional_params.py:
def hello(name):
print(f'Hello, {name}!')
hello('John')
hello('Alice')
В этом коде name является параметром (parameter), который выступает в качестве заполнителя (placeholder) в определении функции. Когда мы вызываем функцию, например, hello('John'), значение 'John' является аргументом (argument), который присваивается параметру name.
Чтобы запустить скрипт, откройте новый терминал в WebIDE, нажав Terminal -> New Terminal в верхнем меню. Затем выполните следующую команду:
python3 ~/project/positional_params.py
Вы увидите следующий вывод, демонстрирующий, что функция дала разные результаты для разных аргументов:
Hello, John!
Hello, Alice!
Если функция определена с позиционными параметрами, вы должны предоставить соответствующий аргумент для каждого из них при вызове. Если этого не сделать, возникнет ошибка.
Использование значений параметров по умолчанию
Часто бывает полезно задать значение по умолчанию для параметра. Если аргумент для этого параметра не передан во время вызова функции, используется значение по умолчанию. Это делает параметр необязательным.
Посмотрим, что произойдет, если вызвать функцию без обязательного аргумента. Откройте файл default_params.py и добавьте следующий код:
def hello(name):
print(f'Hello, {name}!')
hello()
Сохраните файл и запустите его из терминала:
python3 ~/project/default_params.py
Это приведет к ошибке TypeError, поскольку функция hello ожидала один аргумент, но не получила ни одного.
Traceback (most recent call last):
File "/home/labex/project/default_params.py", line 4, in <module>
hello()
TypeError: hello() missing 1 required positional argument: 'name'
Чтобы исправить это, мы можем присвоить значение по умолчанию параметру name. Измените содержимое файла default_params.py, заменив его следующим кодом:
def hello(name="World"):
print(f'Hello, {name}!')
hello()
hello("Jobs")
Теперь снова запустите скрипт:
python3 ~/project/default_params.py
Вывод будет следующим:
Hello, World!
Hello, Jobs!
Первый вызов использует значение по умолчанию "World", в то время как второй вызов использует переданный аргумент "Jobs".
Важное правило: В определении функции все параметры без значений по умолчанию должны располагаться перед любыми параметрами со значениями по умолчанию. Например, def func(a, b="default") является корректным, а def func(a="default", b) вызовет SyntaxError.
Передача аргументов с использованием ключевых слов
При вызове функции вы можете явно указать, для каких параметров вы предоставляете аргументы. Они называются именованными аргументами (keyword arguments). Их главное преимущество в том, что порядок не имеет значения, что может сделать ваш код более читаемым.
Откройте файл keyword_args.py и добавьте следующий код:
def person(name, age):
print(f"{name} is {age} years old.")
## Вызов с именованными аргументами — порядок не имеет значения
person(name="Zhang San", age=25)
person(age=50, name="Li Si")
Сохраните файл и запустите его из терминала:
python3 ~/project/keyword_args.py
Вы увидите, что оба вызова работают корректно, независимо от порядка аргументов:
Zhang San is 25 years old.
Li Si is 50 years old.
Вы также можете смешивать позиционные и именованные аргументы в одном вызове функции. Однако вы должны соблюдать одно правило: все позиционные аргументы должны предшествовать любым именованным аргументам.
Теперь замените содержимое keyword_args.py следующим кодом, чтобы увидеть это правило в действии:
def person(name, age):
print(f"{name} is {age} years old.")
## Это допустимое смешение позиционных и именованных аргументов
person("Wang Wu", age=26)
## Это вызвало бы SyntaxError: positional argument follows keyword argument
## person(age=28, "Zhao Liu")
Снова запустите скрипт. Корректный вызов выполнится как ожидалось.
python3 ~/project/keyword_args.py
Ожидаемый вывод:
Wang Wu is 26 years old.
Обработка переменного числа аргументов
Функции Python могут быть спроектированы так, чтобы принимать переменное число аргументов. Это полезно, когда вы заранее не знаете, сколько аргументов будет передано в вашу функцию.
Переменные позиционные аргументы (*args)
Поместив звездочку * перед именем параметра, вы можете собрать произвольное количество позиционных аргументов в кортеж (tuple). Имя args является соглашением, но вы можете использовать любое допустимое имя параметра.
Переменные именованные аргументы (**kwargs)
Поместив двойную звездочку ** перед именем параметра, вы можете собрать произвольное количество именованных аргументов в словарь (dictionary). Имя kwargs также является соглашением.
Объединим эти концепции. Откройте файл variable_args.py и добавьте следующий код:
## Использование *args для суммирования переменного числа чисел
def calculate_sum(*numbers):
print(f"Arguments received as a tuple: {numbers}")
total = sum(numbers)
print(f"Sum: {total}\n")
## Использование **kwargs для сбора дополнительной информации о профиле
def person_profile(name, age, **other_info):
print(f"Name: {name}")
print(f"Age: {age}")
print(f"Other Info: {other_info}\n")
## Вызов функций
calculate_sum(1, 2, 3)
calculate_sum(10, 20, 30, 40, 50)
person_profile('Wang Wu', 26, gender="Male", job="Writer")
person_profile('Zhao Liu', 28, city="Beijing", status="Active")
Запустите скрипт из терминала:
python3 ~/project/variable_args.py
Вывод показывает, что numbers является кортежем, а other_info — словарем:
Arguments received as a tuple: (1, 2, 3)
Sum: 6
Arguments received as a tuple: (10, 20, 30, 40, 50)
Sum: 150
Name: Wang Wu
Age: 26
Other Info: {'gender': 'Male', 'job': 'Writer'}
Name: Zhao Liu
Age: 28
Other Info: {'city': 'Beijing', 'status': 'Active'}
Изучение специальных типов параметров
Python позволяет вам строго контролировать, как аргументы могут быть переданы в функцию, делая сигнатуру вашей функции более ясной и однозначной. Вы можете указать параметры как исключительно позиционные (positional-only) или исключительно именованные (keyword-only).
Исключительно позиционные параметры (/)
Чтобы указать, что параметры могут быть переданы только по позиции, разместите их перед прямой косой чертой (/) в определении функции.
Исключительно именованные параметры (*)
Чтобы указать, что параметры могут быть переданы только по ключевому слову, разместите их после звездочки (*). Если за * не следует имя параметра, это означает, что все последующие параметры должны быть исключительно именованными.
Посмотрим, как можно комбинировать эти типы. Откройте файл special_params.py и добавьте следующий код. Этот пример определяет функцию с исключительно позиционными, стандартными и исключительно именованными параметрами.
def school_info(name, /, standard_param, *, city):
print(f'Positional-Only (name): {name}')
print(f'Standard (standard_param): {standard_param}')
print(f'Keyword-Only (city): {city}')
print('---')
## В этой функции:
## - `name` должен передаваться по позиции.
## - `standard_param` может передаваться по позиции или по ключевому слову.
## - `city` должен передаваться по ключевому слову.
## Допустимые вызовы
school_info("Peking University", "PKU", city="Beijing")
school_info("Tsinghua University", standard_param="THU", city="Beijing")
## Примеры недопустимых вызовов (закомментированы, чтобы избежать ошибок)
## school_info(name="Zhejiang University", "ZJU", city="Hangzhou") ## TypeError: name is positional-only
## school_info("Fudan University", "FDU", "Shanghai") ## TypeError: city is keyword-only
Запустите скрипт, чтобы увидеть результат допустимых вызовов:
python3 ~/project/special_params.py
Вывод будет следующим:
Positional-Only (name): Peking University
Standard (standard_param): PKU
Keyword-Only (city): Beijing
---
Positional-Only (name): Tsinghua University
Standard (standard_param): THU
Keyword-Only (city): Beijing
---
Этот синтаксис помогает создавать надежные и самодокументируемые функции, уменьшая неоднозначность в том, как их следует вызывать.
Резюме
В этой лабораторной работе вы изучили основы использования параметров в функциях Python. Мы рассмотрели, как определять и вызывать функции с позиционными параметрами, как сделать параметры необязательными, предоставляя значения по умолчанию, и как использовать именованные аргументы (keyword arguments) для более читаемого кода. Вы также изучили, как создавать гибкие функции, которые могут принимать переменное число позиционных (*args) и именованных (**kwargs) аргументов. Наконец, мы рассмотрели специальный синтаксис (/ и *) для принудительного указания способа передачи аргументов, что повышает ясность и надежность ваших функций.



