2017-02-21 4 views
6

this questionits duplicate을 본 후에도 여전히 질문이 남아 있습니다. 내가Python 인터프리터 문자열 풀링 최적화

a = "ab" 
b = "ab" 

a == b 

을 실행 내가 True을받을 경우

내가 왜 is==이 무엇을 얻을.

a = "ab" 
b = "ab" 
a is b # Returns True 

그래서 나는 내 연구를하고 내가 this을 발견이 일이 왜 여기에 문제는 될 것이다. 대답은 파이썬 인터프리터가 문자열 풀링을 사용한다고 말합니다. 따라서 두 개의 문자열이 동일한 것으로 확인되면 최적화를 위해 새 문자열에 동일한 id을 할당합니다.

여기까지는 모든 것이 정확하고 답변되었습니다. 내 진짜 질문은 왜이 풀링은 일부 문자열에 대해서만 발생합니다. 다음은 예입니다.

a = "ab" 
b = "ab" 
a is b # Returns True, as expected knowing Interpreter uses string pooling 

a = "a_b" 
b = "a_b" 
a is b # Returns True, again, as expected knowing Interpreter uses string pooling 

a = "a b" 
b = "a b" 
a is b # Returns False, why?? 

a = "a-b" 
b = "a-b" 
a is b # Returns False, WHY?? 

문자열 풀링이 작동하지 않는 것 같습니다. 이 예제에서는 Python 2.7.6을 사용 했으므로 Python 3에서는이 문제를 해결할 수있을 것이라고 생각했습니다. 그러나 Python 3에서 동일한 예제를 시도한 후에도 동일한 결과가 나타납니다.

질문 : 왜이 예에서는 문자열 풀링이 최적화되어 있지 않습니까? 파이썬이 이것을 최적화하는 것이 더 좋지 않을까요?


편집 : 나는 "a b" is "a b" 반환 True를 실행합니다. 문제는 변수를 사용하면 일부 문자의 경우 False을 반환하지만 다른 문자의 경우 True을 반환하는 이유입니다.

+0

파이썬 3.4.4 창 :'>>> A = "AB"는, 우분투 장 - FrançoisFabre의 python3.4.3는 'FALSE'를 반환 @ B = "AB"는 >>> A는 B TRUE ' –

+0

입니다 –

+0

python 3.5 windows 'ab'는 'a'가 'True'로 평가됩니다. –

답변

4

귀하의 질문은 더 일반적인 질문 "When does python choose to intern a string"는 correct answer문자열 인턴이 특정 구현 점이다의 중복입니다.

CPython 2.7.7에서 문자열의 인터 네킹은이 기사에서 매우 잘 설명됩니다 : The internals of Python string interning. 여기에있는 정보를 통해 귀하의 사례를 설명 할 수 있습니다. 하지 "a b""a-b" 반면

문자열 "ab""a_b"이 구금되는 이유는, 파이썬 식별자 등 전 모습 후자가 없다는 것이다.

당연히 모든 단일 문자열을 인턴하면 런타임 비용이 발생합니다. 따라서 통역사는 주어진 문자열이 인턴쉽을받을 가치가 있는지 여부를 결정해야합니다. 파이썬 프로그램에 사용 된 식별자의 이름이 프로그램의 바이트 코드에 문자열로 포함되어 있기 때문에 식별자와 같은 문자열은 내부에서 이익을 얻을 확률이 높습니다.

상기 문서에서 짧은 발췌 :

함수 all_name_chars 아스키 문자, 숫자 또는 밑줄, 즉의 구성 되지 문자열을 배제문자열은 식별자처럼 보이는 : 'foo' is 'foo'True로 평가하는 반면 'foo!' is 'foo!'False로 평가 이유를 염두에두고 이러한 모든 설명과 함께

#define NAME_CHARS \ 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" 

/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ 

static int 
all_name_chars(unsigned char *s) 
{ 
    static char ok_name_char[256]; 
    static unsigned char *name_chars = (unsigned char *)NAME_CHARS; 

    if (ok_name_char[*name_chars] == 0) { 
     unsigned char *p; 
     for (p = name_chars; *p; p++) 
      ok_name_char[*p] = 1; 
    } 
    while (*s) { 
     if (ok_name_char[*s++] == 0) 
      return 0; 
    } 
    return 1; 
} 

, 우리는 이제 이해합니다.

+0

그것은 꽤 산뜻합니다! 감사! –

+0

링크 된 기사는 훌륭하지만 파이썬 2.7에 관한 내용입니다. 이는 구현 세부 사항이므로 중요합니다. 어쨌든 나는 이것이 속는 사람이라고 생각합니다 : http://stackoverflow.com/questions/10622472/when-does-python-choose-to-intern-a-string –

+0

@Chris_Rands 동의합니다. 답변을 업데이트하고 속임수로 질문을 마무리하기 위해 투표를 추가했습니다. – Leon