У меня есть очень простой пример:Python: разрешение имени; порядок функции ДЕФа
#!/usr/bin/env python
#a() # 1: NameError: name 'a' is not defined
#b() # 1: NameError: name 'b' is not defined
#c() # 1: NameError: name 'c' is not defined
def a():
c() # note the forward use here...
#a() #2: NameError: global name 'c' is not defined
#b() #2: NameError: name 'b' is not defined
#c() #2: NameError: name 'c' is not defined
def b():
a()
#a() #3: NameError: global name 'c' is not defined
#b() #3: NameError: global name 'c' is not defined
#c() #3: NameError: name 'c' is not defined
def c():
pass
a() # these all work OK...
b()
c()
У меня есть 3 функции с именем a()
, b()
и c()
, определенные в исходном файле Python в алфавитном порядке. Тело каждого определения функции - это вызов одной из других функций. Вы можете видеть по моим комментариям, что у меня должен быть первоначальный вызов первой из этих функций НИЖЕ их определений (в текстовом файле), но вам необязательно нужно определение функции над другой функцией, которая ее вызывает.
Конечно, для всех исполняемых функций (в Python и многих других языках), как представляется, обычно используется первый исполняемый код, и теперь я могу понять, почему. В C и C++ файлы заголовков позаботятся об этом. В Паскале вы должны иметь определения имени до их использования.
Предположим, например, что у вас есть это в Python:
def a(a_arg): c(a_arg)
def b(b_arg): a()
def c(a_arg,b_arg): b(b_arg)
a(1)
Он будет не в состоянии должным образом с TypeError: c() takes exactly 2 arguments (1 given)
во время выполнения, когда другие ошибки во время компиляции. (В C, это скомпилировать бы потом не загадочно ...)
В Perl, так как имена подпрограмм обычно решаются во время выполнения, вы можете иметь определения Perl и кода в любом порядке:
#!/usr/bin/env perl
a();
b();
c();
sub a{ c(); }
sub b{ a(); }
sub c{ return; }
В C, это либо ошибка, либо предупреждение (зависит от реализации) для использования функции, которая не была прототипирована и не должна игнорироваться.
Вы можете иметь это:
void a(void) { c(); } /* implicitly assumed to be int c(...) unless prototyped */
void b(void) { a(); }
void c(void) { return; }
int main(void) {
a();
return EXIT_SUCCESS;
}
Моих предположения и путаница заключается в следующем: Если Python не разрешает Подпрограммы имен до момента выполнения, почему источник компилировать фазы проваливаются с упреждающим объявлением имен подпрограмм, которые не были определены еще? Документировано ли где-нибудь (кроме наблюдения другого кода), что вы не можете иметь код в исходном файле над определениями подпрограмм?
Кажется, что Python имеет элементы dynamic name resolution (использование c()
в a()
до его определения ниже в исходном файле) и элементы статического разрешения имен (отказ Python, чтобы запустить вызов a()
при размещении над его определение в исходном файле.)
Есть ли версия Python THIS DOCUMENT, которая охватывает жизненный цикл исполняемого файла Perl и как имена разрешаются между интерпретацией исходного файла и временем выполнения?
Есть ли окончательное описание где-то порядка определений для скрипта Python, который содержит функции, может иметь форвардные определения других имен подпрограмм, но главный код не может?
Редактировать и заключение
После нескольких энергичных комментариев, и некоторые исследования с моей стороны, я пришел к выводу, что мой вопрос действительно больше о том, как имена будут решены, и как пространства имен, прицелы и модули определены в Python.
От carot-top:
«вызываемым должен быть определен до того, как называется в текущем пространстве имен.» и this link по масштабам и именам
От S.Lott:
«Когда имя используется в блоке коды, она будет решена с помощью ближайших охватывающих сфер.» и this link к сроку исполнения скрипта Python.
Из Python документов:
"Область действия определяет видимость имени внутри блока." От Python Execution model
«Модуль может содержать исполняемые операторы, а также определения функций». в more about modules
«На самом деле определения функций также являются« операциями », которые выполняются, выполнение функции уровня модуля вводит имя функции в глобальную таблицу символов модуля». в сноске к ней.
И моя собственная реализация (Duh!), Что:
- исходный файл
Каждый Python трактуется как «модуль» по Python: «Модуль представляет собой файл, содержащий определения Python и заявления»
В отличие от Perl (с которым у меня больше опыта) Python выполняет модули по мере их чтения. Следовательно, сбой сразу исполняемого оператора ссылается на функцию, еще не определенную в том же модуле.
"форвардные определения"? Что это значит? Вы спрашиваете о передовых «ссылках»? Ответ тривиально да. Извините, но вопрос меня смущает. –
Я использовал «форвардное определение» из-за первоначального вопроса о том, когда и где 'def c()' используется в отношении к 'def a()' и в связи с кодом, который немедленно выполняется. В C и Pascal он будет называться «вперед» или «внешним» объявлением прототипом функции в заголовке или иным образом до использования. В Python это иногда имеет значение, но не другие. Еще раз: ** мой вопрос: где документация, которая охватывает это? ** Что можно решить во время выполнения и чего не может быть? Я прочитал документы на веб-сайте Python. – dawg
@ S.Lott: Я всегда думал о «прямой ссылке» как о термине, используемом в двухпроцессорном компиляторе, который не является Python. – dawg