Я новичок в Python, так что это, вероятно, простой вопрос. Следующий код в файле (модуле) Python меня немного смущает:
if __name__ == '__main__':
x = 1
print x
В других языках, на которых я работал, этот код выдает исключение, поскольку x
переменная является локальной для if
оператора и не должна существовать вне ее. Но этот код выполняется и печатает 1. Кто-нибудь может объяснить это поведение? Все переменные, созданные в модуле, глобальны / доступны для всего модуля?
if
выше утверждение не имеет места (то есть,__name__
это не'__main__'
, например , при импорте модуля вместо выполнения его верхнего уровня), тоx
никогда не были связаны, и последующееprint x
заявление броситNameError: name 'x' is not defined
.Ответы:
Переменные Python ограничены самой внутренней функцией, классом или модулем, в котором они назначены. Блоки управления, такие как
if
иwhile
блоки, не учитываются, поэтому переменная, назначенная внутри,if
все еще находится в области видимости для функции, класса или модуля.(Неявные функции, определенные выражением генератора или списком / набором / диктом , имеют значение, как и лямбда-выражения. Вы не можете вставить оператор присваивания ни в один из них, но лямбда-параметры и
for
цели предложения являются неявным присваиванием.)источник
Да, они находятся в одной и той же «локальной области видимости», и на самом деле такой код распространен в Python:
Обратите внимание, что
x
он не объявлен или не инициализирован перед условием, как, например, в C или Java.Другими словами, Python не имеет областей действия на уровне блоков. Будьте осторожны с примерами, такими как
что явно вызовет
NameError
исключение.источник
Область действия в python следует этому порядку:
Поиск в локальной области
Поиск в объеме любых вмещающих функций
Поиск в глобальном масштабе
Поиск встроенных
( источник )
Заметь
if
и другие циклические / ветвящиеся конструкции не перечислены - только классы, функции и модули обеспечивают область действия в Python, поэтому все, что объявлено вif
блоке, имеет ту же область, что и все, что объявлено вне блока. Переменные не проверяются во время компиляции, поэтому другие языки выдают исключение. В Python, пока переменная существует в то время, когда вы в ней нуждаетесь, исключение не будет выдано.источник
Как сказал Илай, Python не требует объявления переменных. В Си вы бы сказали:
но в Python объявление неявно, поэтому, когда вы присваиваете x, оно объявляется автоматически. Это потому, что Python динамически типизирован - он не будет работать на статически типизированном языке, потому что в зависимости от используемого пути переменная может использоваться без объявления. Это будет обнаружено во время компиляции на статически типизированном языке, но с динамически типизированным языком это разрешено.
Единственная причина, по которой статически типизированный язык ограничен необходимостью объявлять переменные вне
if
операторов из-за этой проблемы. Охватите динамику!источник
В отличие от таких языков, как C, переменная Python находится в области действия всей функции (или класса, или модуля), где она появляется, а не только в самом внутреннем «блоке». Это как если бы вы объявили
int x
в верхней части функции (или класса, или модуля), за исключением того, что в Python вам не нужно объявлять переменные.Обратите внимание, что существование переменной
x
проверяется только во время выполнения - то есть, когда вы попадаете вprint x
оператор. Если__name__
не равны"__main__"
, то вы получите исключение:NameError: name 'x' is not defined
.источник
Да. Это также верно для
for
объема. Но не функции, конечно.В вашем примере: если условие в
if
выражении ложно, оноx
не будет определено.источник
Вы выполняете этот код из командной строки, поэтому
if
условия верны иx
установлены. Для сравнения:источник
И обратите внимание, что поскольку типы Python проверяются только во время выполнения, вы можете иметь такой код:
Но мне трудно думать о других способах работы кода без ошибок из-за проблем с типами.
источник