ошибка в определении функции не будет обнаружена в Python? - PullRequest
0 голосов
/ 21 февраля 2012

Вот модуль Python,

#a.py

def bar():
    print x  #x not defined, apparently will result in an error

def foo():
    pass

if __name__ == '__main__':
    foo()

Вышеупомянутый модуль может быть запущен ($ python a.py) без каких-либо ошибок.Зачем?Просто потому, что bar не используется в __main__?

Но определение bar выполняется, не так ли?

Ответы [ 3 ]

4 голосов
/ 21 февраля 2012

Да, определение bar выполнено, но определение не содержит ошибки. Это допустимый Python для определения функции, которая ссылается на глобальные переменные, которые еще не существуют, если они существуют при вызове функции. Учтите это:

def bar():
    print x

x = 10
if __name__ == '__main__':
    bar()

Это не приводит к ошибке. И это только разумно, поскольку даже если x существует в то время, когда функция определена, ничто не помешает вам использовать del позже. Точка, когда необходимо определить x, - это когда bar вызывается (если когда-либо), а не когда bar определено.

Если бы Python работал так, как вы предлагаете, то было бы невозможно определить взаимно рекурсивные функции без странных хаков, таких как временное связывание одного имени с None, а затем определение обеих функций.

РЕДАКТИРОВАТЬ: Чтобы уточнить ответ Игнасио на вопрос Олкотта в комментариях, да синтаксические ошибки обнаруживаются до того, как функция может быть выполнена, но на самом деле они обнаруживаются до того, как ее можно определить. 1017 *

Когда Python загружает файл, он анализирует все содержимое в операторах и затем выполняет операторы по одному. Синтаксическая ошибка означает, что он не смог успешно определить, какие операторы содержит файл, поэтому он не может выполнить что-либо . Таким образом, ошибка будет возникать при загрузке файла, что означает, что либо при непосредственном запуске его с интерпретатором, либо при import.

Этот этап предварительной обработки известен как «время компиляции», хотя Python обычно не рассматривается как скомпилированный язык; он технически скомпилирован в формат байтового кода, но это почти совершенно неинтересно, потому что байтовый код в значительной степени просто непосредственно представляет операторы исходного кода.

1 голос
/ 21 февраля 2012

Это правда, что определение из bar выполняется при запуске сценария.Однако Python не может определить, существует ли глобальная переменная с именем x до тех пор, пока весь скрипт не будет запущен.

Например, вы можете сделать:

if __name__ == '__main__':
    if random.random() < 0.5:
        x = 5
    foo()

Компилятор не будет 'в время компиляции невозможно определить, будет ли x существовать или нет.

1 голос
/ 21 февраля 2012

Python разрешает поиск имен во время выполнения.

def bar():
  print x

x = 3
bar()
...