perl의 무한 루프에 대한이 질문에 흥미가 있습니다. while (1) Vs. for (;;) 속도 차이가 있습니까? , 나는 파이썬에서 비슷한 비교를 실행하기로 결정했습니다. 컴파일러가 while(True): pass
및 while(1): pass
에 대해 동일한 바이트 코드를 생성 할 것으로 예상 했지만 실제로 python2.7에서는 그렇지 않습니다.
다음 스크립트 :
import dis
def while_one():
while 1:
pass
def while_true():
while True:
pass
print("while 1")
print("----------------------------")
dis.dis(while_one)
print("while True")
print("----------------------------")
dis.dis(while_true)
다음 결과를 생성합니다.
while 1
----------------------------
4 0 SETUP_LOOP 3 (to 6)
5 >> 3 JUMP_ABSOLUTE 3
>> 6 LOAD_CONST 0 (None)
9 RETURN_VALUE
while True
----------------------------
8 0 SETUP_LOOP 12 (to 15)
>> 3 LOAD_GLOBAL 0 (True)
6 JUMP_IF_FALSE 4 (to 13)
9 POP_TOP
9 10 JUMP_ABSOLUTE 3
>> 13 POP_TOP
14 POP_BLOCK
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
사용 while True
은 눈에 띄게 더 복잡합니다. 왜 이런거야?
다른 컨텍스트에서 파이썬 True
은 1 과 같은 것처럼 작동합니다 .
>>> True == 1
True
>>> True + True
2
while
두 가지를 구별하는 이유는 무엇 입니까?
python3이 동일한 작업을 사용하여 문을 평가한다는 것을 알았습니다.
while 1
----------------------------
4 0 SETUP_LOOP 3 (to 6)
5 >> 3 JUMP_ABSOLUTE 3
>> 6 LOAD_CONST 0 (None)
9 RETURN_VALUE
while True
----------------------------
8 0 SETUP_LOOP 3 (to 6)
9 >> 3 JUMP_ABSOLUTE 3
>> 6 LOAD_CONST 0 (None)
9 RETURN_VALUE
부울이 평가되는 방식에 python3이 변경 되었습니까?
답변
Python 2.x에서는 True
키워드가 아니라 유형 에서 1로 정의 된 내장 전역 상수 일뿐 bool
입니다. 따라서 인터프리터는 여전히의 내용을로드해야합니다 True
. 즉, True
재 할당 가능합니다.
Python 2.7 (r27:82508, Jul 3 2010, 21:12:11)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
>>> True
4
Python 3.x 에서는 진정으로 키워드 이자 실제 상수가됩니다.
Python 3.1.2 (r312:79147, Jul 19 2010, 21:03:37)
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> True = 4
File "<stdin>", line 1
SyntaxError: assignment to keyword
따라서 인터프리터는 while True:
루프를 무한 루프로 대체 할 수 있습니다 .
답변
이것은 옳지 않습니다.
따라서 인터프리터는 while True : 루프를 무한 루프로 대체 할 수 있습니다.
여전히 루프에서 벗어날 수 있습니다. 그러나 그러한 루프의 else
절은 Python 3에서 절대 액세스되지 않는다는 것은 사실입니다. 또한 값 조회를 단순화하면 다음과 같이 빠르게 실행됩니다.while 1
Python 2 .
성능 비교
다소 사소하지 않은 while 루프의 시간 차이를 보여줍니다.
설정
def while1():
x = 0
while 1:
x += 1
if x == 10:
break
def whileTrue():
x = 0
while True:
x += 1
if x == 10:
break
파이썬 2
>>> import timeit
>>> min(timeit.repeat(while1))
0.49712109565734863
>>> min(timeit.repeat(whileTrue))
0.756627082824707
파이썬 3
>>> import timeit
>>> min(timeit.repeat(while1))
0.6462970309949014
>>> min(timeit.repeat(whileTrue))
0.6450748789939098
설명
차이점을 설명하기 위해 Python 2에서
>>> import keyword
>>> 'True' in keyword.kwlist
False
하지만 파이썬 3에서는
>>> import keyword
>>> 'True' in keyword.kwlist
True
>>> True = 'true?'
File "<stdin>", line 1
SyntaxError: can't assign to keyword
True
Python 3의 키워드 이므로 인터프리터는 누군가가 다른 값으로 대체했는지 확인하기 위해 값을 찾을 필요가 없습니다. 그러나 True
다른 값에 할당 할 수 있기 때문에 통역사는 매번 그것을 찾아야합니다.
Python 2에 대한 결론
파이썬 2에 꽉, 장기 실행 루프가있는 경우, 당신은 아마 사용해야합니다 while 1:
대신 while True:
.
Python 3에 대한 결론
while True:
루프를 벗어날 조건이없는 경우 사용하십시오 .
답변
이것은 이미 훌륭한 답변을 가지고있는 7 년 된 질문이지만, 어떤 답변에서도 다루지 않은 질문에 대한 오해로 인해 중복으로 표시된 다른 질문 중 일부에 대해 잠재적으로 혼란 스러울 수 있습니다.
다른 컨텍스트에서 python은 True가 1 인 것처럼 작동합니다.
>>> True == 1
True
>>> True + True
2
while은 왜 둘을 구별합니까?
사실, while
여기서는 전혀 다른 일을하지 않습니다. 그것은 구별 1
하고 True
것을 정확히 같은 방법으로 +
예 않습니다.
2.7 :
>>> dis.dis('True == 1')
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_CONST 1 (1)
6 COMPARE_OP 2 (==)
9 RETURN_VALUE
>>> dis.dis('True == 1')
1 0 LOAD_GLOBAL 0 (True)
3 LOAD_GLOBAL 0 (True)
6 BINARY_ADD
9 RETURN_VALUE
이제 비교 :
>>> dis.dis('1 + 1')
1 0 LOAD_CONST 1 (2)
3 RETURN_VALUE
LOAD_GLOBAL (True)
for each를 방출 True
하고 옵티마이 저가 전역으로 할 수있는 일은 없습니다. 그래서, while
구별하는 1
과 True
동일한 이유로 +
않습니다. (그리고 ==
옵티마이 저가 비교를 최적화하지 않기 때문에 구별하지 않습니다.)
이제 3.6을 비교하십시오.
>>> dis.dis('True == 1')
1 0 LOAD_CONST 0 (True)
2 LOAD_CONST 1 (1)
4 COMPARE_OP 2 (==)
6 RETURN_VALUE
>>> dis.dis('True + True')
1 0 LOAD_CONST 1 (2)
2 RETURN_VALUE
여기서는 LOAD_CONST (True)
최적화 프로그램 이 활용할 수 있는 키워드에 대한를 내 보냅니다 . 그래서 True + 1
하지 않습니다 정확히 같은 이유를 들어 구분 while True
하지 않습니다. ( ==
최적화 프로그램이 비교를 최적화하지 않기 때문에 여전히 구별하지 않습니다.)
코드가 밖으로 최적화되어 있지 않은 경우 한편, 인터프리터는 치료 끝 True
과 1
이러한 경우의 세에서 정확히 같은. bool
(A)의 서브 클래스 int
및 상속에서 그 방법의 대부분은 int
, 그리고True
당신이 일을하고 있는지, 1. 지금의 내부 정수 값을 가지고 while
테스트를 ( __bool__
3.x의에서, __nonzero__
(2.X에서) 비교 __eq__
), 또는 산술 ( __add__
), True
또는 을 사용하든 동일한 메서드를 호출합니다 1
.