- Выражения как аргументы функций
- Вызов функции внутри функции
- Использование функций в составе выражений
- Совмещение функций и выражений
Когда мы пишем программы, нам нужно не просто выполнять отдельные действия, а соединять их друг с другом. Складывать числа, объединять строки, работать с переменными — всё это примеры того, как простые шаги можно комбинировать, получая более сложное поведение.
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
Здесь в одном месте соединилось несколько уровней: вызов функции, арифметическая операция и ещё один вызов функции. Именно так в программировании и строятся более сложные конструкции — из комбинаций простых шагов.
Эта логика рекурсивна: результат любой операции можно снова использовать как часть нового выражения, и так бесконечно глубоко. Но чем больше вложенных вызовов, тем сложнее читать и понимать код. Поэтому программисты стараются находить баланс между выразительностью и понятностью.