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


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

if __name__ == '__main__':
    x = 1

print x

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

7 192

7 ответов:

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

(неявные функции, определяемые выражением генератора или list/set / dict comprehension do граф, как и лямбда-выражения. Вы не можете вставить оператор присваивания в любой из них, но лямбда-параметры и 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 не требует объявления переменной. В C вы бы сказали:

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