Что происходит при вызове функции в Python с круглыми скобками и без них
Что проверяют
Понимаете ли вы, что функция это обычный объект, а круглые скобки это отдельная операция вызова. Вопрос простой на вид, но на нём видно, писал ли человек колбэки, декораторы и обработчики или только линейный код сверху вниз.
Как отвечать
Имя без скобок это ссылка на объект функции: её кладут в переменную, в словарь, передают аргументом, возвращают из другой функции. Скобки после имени запускают вызов, и на месте выражения оказывается результат.
def greet():
return "привет"
f = greet # ссылка на функцию
print(f) # <function greet at 0x...>
print(f()) # приветРазница важна там, где функцию куда-то передают. Аргументом отдают именно ссылку: ключ сортировки, регистрация обработчика, цель потока. Поставили скобки, значит функция выполнилась прямо в этой строке, а дальше уехал её результат, чаще всего None.
Полезно добавить соседние случаи: obj.method это связанный метод, тоже объект, его можно передать; свойство наоборот выглядит как поле, но при обращении вызывает функцию; скобки работают не только с функциями, а с любым объектом, у которого есть __call__, включая сами классы.
Где спотыкаются
Ставят скобки при передаче и получают вызов вместо ссылки. Классика: в цель потока или в обработчик подставляют результат, поток стартует и не делает ничего, потому что работа уже выполнилась синхронно в момент вычисления аргументов.
Наоборот, забывают скобки там, где нужен результат. Проверка истинности такого имени всегда даёт истину, ведь объект функции истинен сам по себе, и условие перестаёт зависеть от данных.
Считают, что имя без скобок это ошибка. Нет, выражение просто вычисляется в объект функции, и вы увидите его представление. Ошибка про невозможность вызова приходит из другой ситуации, когда скобки поставили после объекта, который вызывать нельзя, например после строки.