Какова область действия переменной, инициализированной в инструкции if?
Я новичок в Python, так что это, вероятно, простой вопрос. Следующий код в файле (модуле) Python меня немного смущает:
if __name__ == '__main__':
x = 1
print x
В других языках, в которых я работал, этот код генерирует исключение, поскольку переменная x
является локальной для оператора if
и не должна существовать вне нее. Но этот код выполняет и печатает 1. Может ли кто-нибудь объяснить это поведение? Все переменные, созданные в модуле глобальные/доступны для всего модуля?
Ответы
Ответ 1
Переменные Python привязаны к самой внутренней функции, классу или модулю, в котором они назначены. Блоки управления, такие как блоки if
и while
, не учитываются, поэтому переменная, назначенная внутри if
, по-прежнему привязана к функции, классу или модулю.
(Неявные функции, определенные выражением генератора или пониманием list/set/dict, подсчитываются, как и лямбда-выражения. Вы не можете заполнять оператор присваивания ни одному из них, но параметры лямбда и for
назначение.)
Ответ 2
Да, они находятся в одной и той же "локальной области", и на самом деле такой код обычно используется в Python:
if condition:
x = 'something'
else:
x = 'something else'
use(x)
Обратите внимание, что x
не объявляется или не инициализируется перед условием, например, на C или Java.
Другими словами, Python не имеет областей уровня блока. Однако будьте осторожны с примерами, такими как
if False:
x = 3
print(x)
который явно повысил бы исключение NameError
.
Ответ 3
Область в python следует этому порядку:
(источник)
Обратите внимание, что if
и другие конструкции цикла/ветвления не перечислены - только классы, функции и модули предоставляют область действия в Python, поэтому все, что объявлено в блоке if
, имеет ту же область действия, что и все, что было упущено вне блока. Переменные не проверяются во время компиляции, поэтому другие языки генерируют исключение. В python, пока переменная существует в то время, когда она вам понадобится, исключение не будет выбрано.
Ответ 4
В отличие от языков, таких как C, переменная Python доступна для всей функции (или класса или модуля), где она появляется, а не только в самом внутреннем "блоке". Как будто вы объявили int x
в верхней части функции (или класса или модуля), за исключением того, что в Python вам не нужно объявлять переменные.
Обратите внимание, что существование переменной x
проверяется только во время выполнения, то есть когда вы попадаете в оператор print x
. Если __name__
не равно "__main__"
, вы получите исключение: NameError: name 'x' is not defined
.
Ответ 5
Как сказал Эли, Python не требует объявления переменной. В C вы сказали бы:
int x;
if(something)
x = 1;
else
x = 2;
но в объявлении Python неявно, поэтому, когда вы назначаете x, он автоматически объявляется. Это потому, что Python динамически типизирован - он не будет работать на статически типизированном языке, потому что в зависимости от используемого пути переменная может использоваться без объявления. Это можно было бы поймать во время компиляции на статически типизированном языке, но с динамически типизированным языком, который он разрешил.
Единственная причина, по которой статически типизированный язык ограничивается необходимостью объявлять переменные вне операторов if
из-за этой проблемы. Объявите динамику!
Ответ 6
Да. Это справедливо и для области for
. Но, конечно, не функции.
В вашем примере: если условие в выражении if
ложно, x
не будет определено, хотя.
Ответ 7
вы выполняете этот код из командной строки, поэтому if
условия истинны и x
установлен. Для сравнения:
>>> if False:
y = 42
>>> y
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
y
NameError: name 'y' is not defined