if 문에서 초기화 된 변수의 범위는 무엇입니까?


266

저는 Python을 처음 사용하므로 간단한 범위 지정 질문 일 것입니다. 파이썬 파일 (모듈)의 다음 코드는 약간 혼란 스럽습니다.

if __name__ == '__main__':
    x = 1

print x

내가 일한 다른 언어에서는 x변수가 if명령문에 로컬 이며 외부에 존재해서는 안되므로이 코드는 예외를 발생 시킵니다. 그러나이 코드는 실행되고 1을 인쇄합니다. 누구나이 동작을 설명 할 수 있습니까? 모듈에서 작성된 모든 변수가 전체 모듈에 대해 전역 / 사용 가능합니까?


17
또 다른 특질 당신이 인식되지 않을 수 있습니다 다음 경우 if문이 위 보유하지 않는다 (즉, 사실 __name__입니다 하지 '__main__' 당신이 그것을 최상위을 실행하는 대신에 모듈을 가져올 때, 예를 들어), 다음 x구속하지 않으며, 후속 않았을 것 print x문 를 던질 것 NameError: name 'x' is not defined입니다.
Santa

답변:


302

파이썬 변수는 가장 안쪽에있는 함수, 클래스 또는 모듈에 할당됩니다. 제어와 같은 블록 ifwhile내부 할당 된 변수가 있으므로 블록은 포함되지 않습니다 if여전히 함수, 클래스 또는 모듈에 속합니다.

(암시 적 기능은 발전기의 발현 또는 목록 / 설정 / DICT 이해에 의해 정의 당신은 그 중 하나에 할당 문을 물건 수 없습니다. 같은 람다 표현식을 할, 수,하지만 람다 매개 변수와 for절 목표는 암시 적 과제입니다.)



105

예, 그것들은 같은 "로컬 스코프"에 있으며, 실제로 다음과 같은 코드는 파이썬에서 일반적입니다 :

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

use(x)

참고 x는 예를 들어, C 또는 Java에있을 것 같은 조건 전에 선언되거나 초기화되지 않았습니다.

다시 말해, 파이썬에는 블록 레벨 범위가 없습니다. 그러나 다음과 같은 예를 조심하십시오.

if False:
    x = 3
print(x)

분명히 NameError예외 가 발생합니다.


42

파이썬의 범위는 다음 순서를 따릅니다.

  • 로컬 범위 검색

  • 모든 둘러싸는 기능의 범위를 검색

  • 글로벌 범위 검색

  • 내장 검색

( 소스 )

그 통지 if및 다른 루프 / 분기 구조가 나와 있지 않은 - 선언 것도 있으므로 클래스 만, 함수, 모듈, 파이썬 범위를 제공하는 if어떤 외부 블록을 decleared로 블록이 같은 범위를 갖는다. 컴파일 타임에 변수를 확인하지 않으므로 다른 언어에서 예외가 발생합니다. 파이썬에서는 변수가 필요할 때 변수가 존재하는 한 예외가 발생하지 않습니다.


9

Eli가 말했듯이 파이썬에는 변수 선언이 필요하지 않습니다. C에서는 다음과 같이 말합니다.

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

그러나 파이썬에서는 선언이 암시 적이므로 x에 할당하면 자동으로 선언됩니다. 파이썬은 동적으로 입력되기 때문입니다. 사용되는 경로에 따라 변수가 선언되지 않고 사용될 수 있기 때문에 정적으로 유형이 지정된 언어에서는 작동하지 않습니다. 컴파일 타임에 정적으로 유형이 지정된 언어로 잡히지 만 동적으로 유형이 지정된 언어로 허용됩니다.

정적으로 형식화 된 언어 if가이 문제 때문에 명령문 외부에서 변수를 선언해야하는 유일한 이유 는 다음과 같습니다. 역 동성을 받아들이십시오!


9

C와 같은 언어와 달리, 파이썬 변수는 가장 안쪽의 "블록"뿐만 아니라 그것이 나타나는 모든 함수 (또는 클래스 또는 모듈)의 범위에 속합니다. int x파이썬에서는 변수를 선언 할 필요가 없다는 점을 제외하면 함수 (또는 클래스 또는 모듈)의 최상위에 선언 한 것과 같습니다.

변수의 존재는 x런타임시, 즉 print x명령문에 도달 할 때만 점검됩니다 . __name__같지 않으면 "__main__"예외가 발생 NameError: name 'x' is not defined합니다..


클래스는 범위를 만들지 않습니다. 클래스의 "local"변수는 생성시 클래스의 dict에 간단히 추가됩니다.
chepner

3

예. for범위에 대해서도 마찬가지입니다 . 그러나 물론 기능은 아닙니다.

귀하의 예에서 : if문의 조건 이 거짓이면 x정의되지 않습니다.


2

명령 행에서이 코드를 실행하므로 if조건이 true이고 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

0

또한 파이썬 유형은 런타임에만 검사되므로 다음과 같은 코드를 가질 수 있습니다.

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

그러나 유형 문제로 인해 코드가 오류없이 작동하는 다른 방법을 생각하는 데 어려움을 겪고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.