Я плохо знаком с Python, таким образом, это - вероятно, простой вопрос об обзоре. Следующий код в файле Python (модуль) смущает меня немного:
if __name__ == '__main__':
x = 1
print x
На других языках я работал в, этот код выдал бы исключение, как x
переменная локальна для if
оператор и не должен существовать за пределами него. Но этот код выполняется и печатает 1. Кто-либо может объяснить это поведение? Все переменные создаются в модуле, глобальном/доступном ко всему модулю?
Переменные Python ограничены самой внутренней функцией, классом или модулем, в котором они назначены. Блоки управления, такие как блоки if
и while
, не учитываются, поэтому переменная, назначенная внутри if
, по-прежнему ограничена функцией, классом или модулем.
(Неявные функции, определенные выражением генератора или пониманием списка / набора / словаря , подсчитывают , как и лямбда-выражения. Вы не можете вставлять оператор присваивания ни в одно из них, кроме лямбда-параметров и для
целевые объекты предложения являются неявным назначением.)
В отличие от языков, таких как C, переменная Python находится в области видимости всей функции (или класса, или модуля), где она появляется, а не только в самом внутреннем «блоке». Это как если бы вы объявили int x
в верхней части функции (или класса, или модуля), за исключением того, что в Python вам не нужно объявлять переменные.
Обратите внимание, что существование переменной x
проверяется только во время выполнения, то есть когда вы переходите к оператору print x
. Если __ name __
не равно «__ main __»
, вы получите исключение: NameError: имя 'x' не определено
.
Как сказал Эли , Python не требует объявления переменных. В C вы бы сказали:
int x;
if(something)
x = 1;
else
x = 2;
, но в Python объявление неявно, поэтому, когда вы присваиваете x, оно объявляется автоматически. Это потому, что Python динамически типизирован - он не будет работать на статически типизированном языке, потому что в зависимости от используемого пути переменная может использоваться без объявления. Это будет обнаружено во время компиляции на языке со статической типизацией, но с языком с динамической типизацией это разрешено.
Единственная причина того, что язык со статической типизацией ограничен объявлением переменных вне операторов if
из-за этой проблемы. Примите динамику!
Область видимости в python следует в следующем порядке:
Поиск в локальной области
Поиск в области любых включающих функций
Поиск в глобальной области
Поиск встроенных функций
( источник )
Обратите внимание, что if
и другие конструкции цикла / ветвления не указаны - только классы, функции и модули обеспечивают область видимости в Python, поэтому все, что объявлено в if
блок имеет ту же область видимости, что и все, что объявлено вне блока. Переменные не проверяются во время компиляции, поэтому другие языки выдают исключение. В python, пока переменная существует в то время, когда она вам нужна, исключение не генерируется.
Да, они находятся в одной «локальной области видимости», и на самом деле такой код является обычным в Python:
if condition:
x = 'something'
else:
x = 'something else'
use(x)
Обратите внимание, что x
не объявляется и не инициализируется перед условием, как это будет, например, на C или Java.
Другими словами, Python не имеет областей видимости на уровне блоков. Однако будьте осторожны с такими примерами, как
if False:
x = 3
print(x)
, которые явно вызовут исключение NameError
.
Да. Это также верно для для области
. Но не функции, конечно.
В вашем примере: если условие в операторе if
ложно, x
не будет определено.
вы выполняете этот код из командной строки, поэтому , если
условия истинны и установлено 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