Какова область действия переменной, инициализированной в операторе if?

Я новичок в Python, так что это, вероятно, простой вопрос. Следующий код в файле (модуле) Python меня немного смущает:

if __name__ == '__main__':
    x = 1

print x

На других языках, на которых я работал, этот код выдает исключение, так как x переменная является локальной для if заявление и не должно существовать вне его. Но этот код выполняется и печатает 1. Кто-нибудь может объяснить это поведение? Все переменные, созданные в модуле, глобальны / доступны для всего модуля?

7 ответов

Решение

Переменные Python ограничены самой внутренней функцией, классом или модулем, в котором они назначены. Блоки управления, такие как if а также while блоки не учитываются, поэтому переменная, назначенная внутри if все еще ограничен функцией, классом или модулем.

(Неявные функции, определенные выражением генератора или списком / набором / диктом , имеют значение, как и лямбда-выражения. Вы не можете вставить оператор присваивания ни в один из них, кроме лямбда-параметров и for цели предложения являются неявным присваиванием.)

Да, они находятся в одной и той же "локальной области видимости", и на самом деле такой код распространен в Python:

if condition:
  x = 'something'
else:
  x = 'something else'

use(x)

Обратите внимание, что x не объявляется или не инициализируется до условия, как, например, в C или Java.

Другими словами, Python не имеет областей действия на уровне блоков. Будьте осторожны с примерами, такими как

if False:
    x = 3
print(x)

который явно поднимет NameError исключение.

Область действия в python следует этому порядку:

  • Поиск в локальной области

  • Поиск в объеме любых вмещающих функций

  • Поиск в глобальном масштабе

  • Поиск встроенных модулей

( источник)

Заметить, что if и другие циклические / ветвящиеся конструкции не перечислены - только классы, функции и модули обеспечивают область видимости в Python, поэтому все, что объявлено в if блок имеет ту же область видимости, что и все, что объявлено вне блока. Переменные не проверяются во время компиляции, поэтому другие языки выдают исключение. В python, пока переменная существует в то время, когда вы в ней нуждаетесь, исключение не будет выдано.

В отличие от языков, таких как C, переменная Python находится в области действия всей функции (или класса, или модуля), где она появляется, а не только в самом внутреннем "блоке". Это как если бы вы заявили int x в верхней части функции (или класса, или модуля), за исключением того, что в Python вам не нужно объявлять переменные.

Обратите внимание, что существование переменной x проверяется только во время выполнения - то есть, когда вы добираетесь до print x заявление. Если __name__ не равно "__main__" тогда вы получите исключение: NameError: name 'x' is not defined,

Как сказал Илай, Python не требует объявления переменных. В Си вы бы сказали:

int x;
if(something)
    x = 1;
else
    x = 2;

но в Python объявление неявное, поэтому, когда вы присваиваете x, оно объявляется автоматически. Это потому, что Python динамически типизирован - он не будет работать на статически типизированном языке, потому что в зависимости от используемого пути переменная может использоваться без объявления. Это будет обнаружено во время компиляции на статически типизированном языке, но с динамически типизированным языком это разрешено.

Единственная причина, по которой статически типизированный язык ограничен объявлением переменных за пределами if заявления в из-за этой проблемы. Охватите динамику!

Да. Это также верно для for объем. Но не функции, конечно.

В вашем примере: если условие в if утверждение ложно, x не будет определяться, хотя.

Поэтому вы выполняете этот код из командной строки 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

И обратите внимание, что, поскольку типы Python проверяются только во время выполнения, вы можете иметь такой код, как:

if True:
    x = 2
    y = 4
else:
    x = "One"
    y = "Two"
print(x + y)

Но мне сложно придумать другие способы работы кода без ошибок из-за проблем с типом.

Другие вопросы по тегам