Python: Вызов функции — выражение
Когда мы пишем программы, нам нужно не просто выполнять отдельные действия, а соединять их друг с другом. Складывать числа, объединять строки, работать с переменными — всё это примеры того, как простые шаги можно комбинировать, получая более сложное поведение.
rate = 10
hours = 5
salary = rate * hours + 100
print(salary) # => 150
В программировании для этого используется понятие выражение. Оно обозначает конструкцию, которая вычисляется и даёт результат. В примере выше rate * hours + 100
— это выражение, составленное из переменных (rate
, hours
), числового литерала (100
) и арифметических операций. Всё вместе оно возвращает результат, который можно сохранить в переменную или использовать дальше.
Что нам даёт это знание? Мы понимаем, что выражения можно комбинировать бесконечно, постепенно усложняя логику. Каждое новое выражение становится частью большего:
bonus = 50
# Выражение из множества операций
salary = (rate * hours + bonus) * 12 - 500
print(salary)
Здесь несколько выражений объединены в одно, и результат стал ещё сложнее. Именно так строятся программы — маленькие шаги складываются в большие конструкции. Поэтому в программировании невозможно заранее заучить все комбинации. Гораздо важнее понимать сам принцип: как можно соединять выражения между собой, чтобы получить нужный результат.
Выражения как аргументы функций
Аргументом функции всегда является какое-то значение. Но значение не обязательно записывать напрямую — его можно вычислить. А значит, в аргументы функции можно подставлять любые выражения.
# Здесь аргумент функции print — это число 150
print(150)
# А здесь аргумент — выражение, которое сначала вычисляется
print(10 * 15) # => 150
# Можно комбинировать ещё сложнее
rate = 10
hours = 15
bonus = 50
print(rate * hours + bonus) # => 200
Функция print()
просто получает готовое значение и выводит его на экран. Каким образом это значение было получено — не имеет значения. Именно поэтому вызовы функций отлично сочетаются с любыми выражениями.
Вызов функции внутри функции
Так как вызов функции сам по себе является выражением, его результат можно сразу передавать другой функции. Это позволяет строить ещё более сложные конструкции.
name = 'python'
# Вызов len(name) возвращает 6
# Этот результат сразу используется как аргумент print()
print(len(name)) # => 6
Здесь len(name)
вычисляется первым и отдаёт результат — число 6. Затем это значение подставляется в вызов print()
. Такая комбинация может быть сколько угодно глубокой: результат одной функции можно использовать в другой, а потом ещё в следующей.
Чтобы правильно читать такие конструкции, нужно помнить про порядок вызова:
- Сначала выполняется функция, которая находится «внутри» — в нашем случае это
len(name)
. - Затем её результат подставляется на место вызова.
- После этого выполняется внешняя функция — здесь это
print()
.
Таким образом, код print(len(name))
можно мысленно разложить так:
len(name)
→6
print(6)
- На экране появляется
6
.
Этот принцип работает всегда: сначала вычисляются вложенные вызовы, потом внешний.
Хозяйке на заметку. Существую языки, где вычисление идет в обратном порядке. Они работают за счет ленивости, то есть вычисление внутренних вызовов не происходит до тех пор, пока это не станет нужным (когда кто-то попытается использовать значение). Таким языком является Haskell.
Использование функций в составе выражений
Функции возвращают значения, а значит их вызовы можно использовать не только как аргументы других функций, но и как часть любых других выражений.
name = 'python'
# Вызов len(name) возвращает 6
# Мы вычитаем 1, чтобы получить индекс последнего символа
last_index = len(name) - 1
print(last_index) # => 5
# Можно использовать результат функции в арифметике
text = 'hexlet'
double = len(text) * 2
print(double) # => 12
Здесь вызовы len(name)
и len(text)
— это полноценные выражения. Они возвращают значения, которые можно комбинировать с числами, переменными и другими операциями.
Совмещение функций и выражений
Мы уже видели, что функции можно использовать как часть выражений и что вызов одной функции можно передавать в другую. Эти идеи легко соединяются.
name = 'python'
# Вызов функции len(name) возвращает 6
# Затем мы вычитаем 1 и получаем индекс последнего символа
# Всё это выражение сразу используется как аргумент print()
print(len(name) - 1) # => 5
Здесь в одном месте соединилось несколько уровней: вызов функции, арифметическая операция и ещё один вызов функции. Именно так в программировании и строятся более сложные конструкции — из комбинаций простых шагов.
Эта логика рекурсивна: результат любой операции можно снова использовать как часть нового выражения, и так бесконечно глубоко. Но чем больше вложенных вызовов, тем сложнее читать и понимать код. Поэтому программисты стараются находить баланс между выразительностью и понятностью.
Задание
Выведите на экран первую и последнюю буквы предложения, записанного в переменную text
, в следующем формате:
First: N
Last: t
Постарайтесь создать только одну переменную, в которую сразу запишется нужный текст перед печатью на экран. В этом уроке мы отрабатываем умение собирать составное выражение.
Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект
Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества
Ваше упражнение проверяется по этим тестам
from hexlet.test import expect_output
def test(capsys):
expected = "First: N\nLast: t"
expect_output(capsys, expected)
Решение учителя откроется через:
20:00
