Как python реализует взаимную рекурсию?
Переходя к python с фоном C/Java, мне недавно пришлось реализовать взаимную рекурсию, но что-то в python беспокоит меня:
поскольку программа python интерпретируется по строкам, если у меня есть две функции один за другим в одном файле python:
def A(n):
B(n-1)
# if I add A(1) here, it gives me an error
def B(n):
if n <= 0:
return
else:
A(n-1)
Когда интерпретатор читает A
, B
еще не определен, однако этот код не дает мне ошибку
TL; DR
Я понимаю, что, когда def
интерпретируется, python добавляет запись в какое-то локальное пространство имен locals()
с {"function name": function address}
,
но что касается тела функции, он выполняет только проверку синтаксиса:
def A():
blabla # this will give an error
def B():
print x # even though x is not defined, this does not give an error
A() # same as above, NameError is only detected during runtime
Ответы
Ответ 1
A SyntaxError
будет обнаружен во время компиляции, но большинство других ошибок (NameError
, ValueError
и т.д.) будут обнаружены только во время выполнения, а затем только при вызове этой функции.
", если я написал функцию, если ее не вызвал в моем тесте.." - и именно поэтому вы должны проверить все.
Некоторые IDE будут вызывать предупреждения в разных ситуациях, но лучший вариант - провести тщательное тестирование самостоятельно. Таким образом, вы также можете проверить наличие ошибок, возникающих с помощью таких факторов, как пользовательский ввод, которые автоматические проверки IDE не будут покрываться.
Ответ 2
В строке B(n-1)
говорится: "Когда этот оператор выполняется, найдите в модуле некоторую функцию B
, затем вызовите ее с параметрами n-1
". Поскольку поиск выполняется, когда функция выполняется, B
может быть определена позже.
(Кроме того, вы можете полностью перезаписать B
с помощью другой функции, а A
будет вызывать новый B
, но это может привести к некорректному коду.)
Если вы беспокоитесь о том, что не поймаете вызовы несуществующих функций, вы можете попробовать использовать инструменты статического анализа. Помимо этого, убедитесь, что вы тестируете свой код.
Ответ 3
Когда интерпретатор читает A, B еще не определен, однако этот код не дает мне ошибку
Причина, по которой интерпретатор python не дает ошибку, можно найти из docs, который называется переслать ссылку технически:
Разрешение имен свободных переменных возникает во время выполнения, а не во время компиляции.