2010-05-13 3 views
156

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

if __name__ == '__main__': 
    x = 1 

print x 

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

+7

Еще одна уловка, о которой вы, возможно, и не подозревали: если оператор 'if' выше недействителен (т. Е.' __name__' is * not * ''__main __'', например, когда вы импортируете модуль вместо его выполнения top-level), то 'x' никогда не будет привязан, а последующий оператор' print x' будет вызывать 'NameError: name 'x' не определен'. – Santa

ответ

155

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

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

36

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

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

use(x) 

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

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

if False: 
    x = 3 
print(x) 

, который бы четко поднять NameError исключение.

1

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

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

1

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

Scope в питоне следует этому порядок:

  • Искать локальную область видимости

  • Искать сферу любых функций ограждающего

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

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

(source)

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

5

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

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

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

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

7

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

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

+0

Классы не создают область; «локальная» переменная в классе просто добавляется к типу класса при создании. – chepner

Смежные вопросы