2012-08-07 7 views
7

최근에 파이썬 생성기를 조금 실험 해 보았습니다. 다음과 같은 호기심 많은 행동을 보았습니다. 왜 이런 일이 벌어지고 어떤 일이 벌어지는 지 궁금합니다.Python - 호기심/예기치 않은 동작 - 연산자의 우선 순위

def generating_test(n): 
    for a in range(n): 
     yield "a squared is %s" % a*a # Notice instead of a**2 we have written a*a 

for asquare in generating_test(3): 
    print asquare 

출력 :

a squared is 1 
a squared is 2a squared is 2 

예상 출력을 생성하는 다음 스크립트 대 :

def generating_test(n): 
    for a in range(n): 
     yield "a squared is %s" % a**2 # we use the correct a**2 here 

for asquare in generating_test(3): 
    print asquare 

출력 :이 발전기와 아무 상관이없는

a squared is 0 
a squared is 1 
a squared is 4 
+1

따로 : 실제로 정수를 포맷하려면'% s'이 아니라'% d'을 사용하십시오. – kojiro

+5

또는 새로운'format' 구문을 사용하십시오. 내가 처음 보았을 때 조금 길다는 생각이 들었지만 나는 그것을 좋아하게되었다. – DSM

+0

동료가 한 번 말했듯이, * 항상 * '%'다음에 튜플을 사용하십시오. – chepner

답변

20

는 :

>>> a = 2 
>>> "a squared is %s" % a 
'a squared is 2' 
>>> ("a squared is %s" % a)*a 
'a squared is 2a squared is 2' 
>>> "a squared is %s" % a*a 
'a squared is 2a squared is 2' 
>>> "a squared is %s" % (a*a) 
'a squared is 4' 

% 영업 이익은 캐릭터 라인 및 인수로 첫 a를 사용하여 곱셈 전에 수행된다. 귀하의 a**2은 및 2을 인수로 사용하여 ** 연산을 수행하기 때문에 %보다 먼저 계산됩니다.

+0

그것은 빨랐다! – jamylak

+2

yeh 그것을 나에게 이긴다 ... 간신히 : P –

+0

매우 흥미 롭습니다. 빠른 응답에 감사드립니다. 나는 받아 들일 수있는 것으로 표시되기까지 11 분을 기다려야합니다. 관련성이 없으므로 발전기 및 출력량에 대한 태그를 제거했습니다. –

8

Python's order of operations은 PEMDAS가 적용되는 경우를 제외하고는 왼쪽에서 오른쪽입니다. 당신이 지수의 으뜸 입증 한대로, 그러나

>>> print 3 * "a foo %s" % 'hi' 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: not enough arguments for format string 
>>> print 3 * "a foo %s" % ('hi', 'ho', 'yo') 
a foo hia foo hoa foo yo 

: 당신이 보간의 왼쪽 곱셈을 만드는 순서를 반대로하는 경우 때문에 문자열 보간 연산자는 분명히이 우선, 모듈 및 곱셈과 같은 우선 순위가 왼쪽에서 오른쪽 순서로.

업데이트 :

... % 연산자도 (도 보간라고도 함) 문자열 서식을 수행 에 문자열과 유니 코드 객체에 의해 오버로드 : 그것은 denotatively 분명하지만, 함축적으로 관련 뭔가를 주장하는 same document under Binary Arithmetic Operations에서. 그 단지 % 운영자 무엇을 말하는 것으로 보인다 동안

, 나는 그것의 위치와 상황도 그것이 또는 보간 모듈로 사용되는 여부 같은 우선 순위가 알려줍니다 생각합니다.

+2

이 문서의 끝 부분에 요약되어 있으므로 특히 주석 8에서는 "% 연산자는 문자열 서식 지정에도 사용되며 동일한 우선 순위가 적용됩니다"라고 명시되어 있습니다. – lvc

+0

그렇지 않다면 상상해보십시오 ... 하위 표현식의 런타임 유형을 알기 전까지는 파이썬 코드를 구문 분석 할 수 없습니다! – Aaron

+0

@Aaron * 그들이 존재하지 않으면 상황이 너무 달라집니다. * - [Anna Russell] (http://en.wikipedia.org/wiki/Anna_Russell). [annotations] 유형 (http://www.python.org/dev/peps/pep-3107/)이 파이썬에서 필요로하고 컴파일 타임에 유형을 적용하는 데 사용되면 다른 언어이지만 미친 생각은 아닙니다 . :) – kojiro

5

예기치 않은 동작이 관찰되면 가장 간단한 경우로 분석하여 분석을 시작하십시오. 간단한 사례는 쉽게 연구하고 이해할 수 있습니다.

예상치 못한 행동 :

>>> 'hello %s' % 3 * 2 
'hello 3hello 3' 

이 (당신은 'hello 6' 예상)


우리는 파이썬이 'hello 3' * 2보다는 'hello %d' % 6로 명령을 해석해야한다 추론.괄호로 두 번째 해석을 시도합니다.

>>> "hello %s" % (3*2) 
'hello 6' 

유레카!

우리는 문자열 형식 지정 연산자 %이 곱하기보다 더 크거나 같은 우선 순위를 갖고 있음을 입증했습니다. - 우리는 파이썬 문서를 확인 예는이 http://docs.python.org/reference/expressions.html#summary

은 우선 순위가 동일한 것을 확인하려면 확인, 우리는 그것을 다른 방법으로 주위 시도 할 수 있습니다 : 쉼표 (,)가 중복되는 것을보고

>>> "%d,"*2%(1,2) 
'1,2,' 

을, 우리 그 이유는 문자열 형식이 %이되기 전에 곱셈 "%d," * 2을 수행했기 때문입니다. 곱셈이 문자열 서식보다 선행 할 수 있고 문자열 서식이 곱하기보다 우선하는 경우 우선 순위가 동일해야합니다.