파이썬 'for'루프에서 범위 지정


177

파이썬의 범위 지정 규칙에 대해서는 묻지 않습니다. 파이썬 for 루프에서 범위 지정이 어떻게 작동 하는지 일반적으로 이해 합니다 . 내 질문은 디자인 결정이 이런 식으로 내려 졌는가입니다. 예를 들어 (말장난 의도가 없음) :

for foo in xrange(10):
    bar = 2
print(foo, bar)

위는 (9,2)를 인쇄합니다.

'foo'는 실제로 루프를 제어하고 'bar'는 루프 내부에 정의되었습니다. 루프 외부에서 'bar'에 액세스 해야하는 이유를 이해할 수 있습니다 (그렇지 않으면 for 루프의 기능이 매우 제한적 임). 내가 이해하지 못하는 것은 루프가 끝난 후에 제어 변수가 범위 내에 있어야하는 이유입니다. 내 경험상 단순히 전역 네임 스페이스를 어지럽히고 다른 언어의 통역사가 잡을 수있는 오류를 추적하기가 더 어려워집니다.


6
for루프가 전역 네임 스페이스를 어지럽히 지 않게하려면 함수로 래핑하십시오. 폐쇄 폐쇄!
자탄 교

24
전역 네임 스페이스에서 루프를 실행하지 않으면 (흔하지 않은) 로컬 네임 스페이스 가 복잡해 집니다.
Glenn Maynard

3
이것이 존재하지 않으면 루프 내부에서 중단 한 지점에서 나중에 처리를 어떻게 계속 하시겠습니까? 루프 전에 제어 변수 정의하십시오 .
endolith

9
@endolith 그래 ... 왜 필요하지 않습니까?
Steven Lu

3
사람들은 단지 그들이하는 일을 선호 할 것입니다. 나는 이런 종류의 일이 이런 종류의 일에 익숙해 져 다른 언어로 전환 할 때 고통스러운 과정을 거쳐야하는 파이썬 코더를 아프게한다고 말하고 싶습니다. 우리의 나머지 부분은 내가 생각하는 깔끔한 작은 지름길입니다.
Steven Lu

답변:


107

가장 쉬운 대답은 문법을 단순하게 유지하고 채택하기에 걸림돌이되지 않았으며 많은 사람들이 루프 구조 내에서 할당 할 때 이름이 속하는 범위를 명확하게하지 않아도되는 것에 만족했다는 것입니다. 변수는 범위 내에서 선언되지 않으며 할당 문의 위치에 의해 암시됩니다. global키워드는 바로 이러한 이유 때문에 (즉, 할당을 의미하는 세계적인 범위에서 수행됩니다) 존재합니다.

최신 정보

여기 주제에 대한 좋은 토론이 있습니다 : http://mail.python.org/pipermail/python-ideas/2008-October/002109.html

루프에 대해 for-loop 변수를 로컬로 만들기위한 이전의 제안은 루프를 종료 한 후 값을 유지하는 루프 변수에 의존하는 기존 코드의 문제를 우연히 발견했으며 이는 바람직한 기능으로 간주됩니다.

요컨대, 파이썬 커뮤니티에서 비난 할 수 있습니다.


2
유도 변수의 범위가 루프의 본문으로 제한되면 문법이 어떻게 더 복잡해 집니까? 이러한 변화는 문법이 아니라 파이썬의 의미 론적 분석에 국한 될 것이다.
Charles

6
루프는 파이썬에서 블록이 아닙니다. 이런 종류의 행동 변화는 문법을 근본적으로 바꾸거나 특별한 경우를 제공해야합니다. 유도 변수의 전체 개념은 현재 문법으로 표현되지 않습니다. 문법은 통역사가 어떻게 해석 할 것인지에 대한 계약을 제공합니다. 내 요점은 문법을 더 복잡하게 만들지 않으면 서이 행동의 변화가 어떻게 이루어질 수 있는지 예측할 수 없다는 것입니다. 디자인 결정의 부작용이 특징이 되었기 때문에 모두 문제가되었습니다.
Jeremy Brown

1
이 게시물은 mail.python.org/pipermail/python-dev/2005-September/056677.html에서 Brown 씨가 주장하는 속도와 합병증에 대한 자세한 내용을 제공합니다.
rajesh

62

파이썬에는 다른 언어 (예 : C / C ++ 또는 Java)와 마찬가지로 블록이 없습니다. 따라서 파이썬에서 범위를 정하는 것은 함수입니다.


3
혼란 스러워요-파이썬이 함수의 범위와 같은 방식으로 for 루프의 범위를 지정하지 못하게하는 것은 무엇입니까?
키메라 코더

36
사실이 아니라, 단지 문법이 막히지 않는 것입니다. ( docs.python.org/reference/… ) "블록은 하나의 단위로 실행되는 파이썬 프로그램 텍스트입니다. 다음은 블록입니다 : 모듈, 함수 본문 및 클래스 정의 ..."
Jeremy

1
@thebackhand, 아무것도. 그것은 단지 불필요하다고 간주되었습니다.
habnabit

@Jeremy Brown-참으로. 좋은 메모입니다.
atzz

6
@thebackhand-블록이있는 언어에서 범위 지정 for루프는 일반적인 원칙의 자연스러운 확장입니다. 파이썬에서는 특별한 경우가되어야하며, 특별한 이점이 없다면 특별한 경우는 피해야합니다.
atzz

39

이것에 대한 정말 유용한 경우는 enumerate 는 결국 총 수를 원합니다.

for count, x in enumerate(someiterator, start=1):
    dosomething(count, x)
print "I did something {0} times".format(count)

이것이 필요합니까? 아니요. 그러나 편리합니다.

알아야 할 또 다른 사항 : Python 2에서는 목록 이해의 변수도 유출됩니다.

>>> [x**2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> x
9

그러나 Python 3에는 동일하게 적용되지 않습니다.


4
당신은 아마도 else절 에서 그렇게 할 수 있습니다 . else: print "I did something {0} times".format(count)-로컬 범위 (파이썬에는 존재하지 않음)가 사라지기 전에
Nas Banov

3
파이썬 3에서는 두 번째 예제 만 작동하지 않습니다. 첫 번째는 여전히? 왜 파이썬 3에서 제거되었는지에 대한 메모?
endolith

7
count, enumerate (a, start = 1)의 항목 : # 기본 인덱스는 0부터
Tao Zhang

3
첫 번째 예는 좋은 사용 사례가 아니라이 범위 지정 규칙이 위험하고 의존해서는 안된다는 증거와 비슷합니다. 어떤 경우는 someiterator비어?
최대

1
@Nas else이 경우에 절을 사용할 수 있지만 루프 본문이 break조기에 수행 될 수 있으므로 일반적으로 작동하지 않습니다 .
jamesdlin

2

루프에 break 문이 있고 나중에 반복 값을 사용하여 백업하거나 무언가를 색인화하거나 상태를 지정하려는 경우 한 줄의 코드와 하나의 할당이 저장되므로 편리합니다.


1

Python의 주요 영향 중 하나는 ABC 에서 초보자에게 프로그래밍 개념을 가르치기 위해 네덜란드에서 개발 한 언어입니다. 파이썬의 제작자 인 Guido van Rossum은 1980 년대에 ABC에서 일했습니다. 나는 ABC에 대해 거의 아무것도 알지 못하지만 초보자를위한 것이므로 초기 BASIC과 같이 제한된 수의 범위를 가져야한다고 생각합니다.


-1

우선 변수가 루프에 대해 로컬 인 경우 해당 루프는 대부분의 실제 프로그래밍에 쓸모가 없습니다.

현재 상황에서 :

# Sum the values 0..9
total = 0
for foo in xrange(10):
    total = total + foo
print total

수율 45. 이제 파이썬에서 할당이 어떻게 작동하는지 고려하십시오. 루프 변수가 엄격하게 로컬 인 경우 :

# Sum the values 0..9?
total = 0
for foo in xrange(10):
    # Create a new integer object with value "total + foo" and bind it to a new
    # loop-local variable named "total".
    total = total + foo
print total

할당 후 루프 내부는 루프 외부 와 동일한 변수가 아니기 0때문에 yields 입니다. 이것은 최적이거나 예상되는 동작이 아닙니다.totaltotal


5
질문에 대답하지 않습니다. OP는 총계가 아닌 foo에 대해 묻고있었습니다 (또는 예제에서 막대).
James Bradbury

6
@JamesBradbury total와는 foo여전히 영업 이익의 시나리오에서 루프 지역 바인딩을 가질 것이고 로직은 동일합니다.
Kirk Strauser

2
OP : "루프 외부에서 'bar'에 액세스해야하는 이유를 이해할 수 있습니다 (그렇지 않으면 루프의 기능이 매우 제한적 임). 이해하지 못하는 것은 제어 변수 를 유지 해야하는 이유 입니다. 루프 종료 후 범위 내에 있습니다. " (강조 광산)
James Bradbury

2
@JamesBradbury 당신은 옳을 지 모르지만, 나는이 3 년 전에 대답했고 지금은 토론 할 가치가 없을 것입니다.
Kirk Strauser
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.