String comparison

 

str 비교할 때 id()를 비교하는 is 를 주로 사용했었는데 같은 문자열인데도 다르게 인식하는 경우가 있더라고요.

1
2
3
4
5
6
7
8
9
10
# ex.txt
# res


with open("ex.txt", 'r') as f:
    r1 = f.read()
r2 = 'res'

print(r1, r2)
r1 is r2, r1 == r2
res res
(False, True)
1
2
3
4
5
r3 = 'res'
r4 = 'res'

print(r3, r4)
r3 is r4, r3 == r4
res res
(True, True)

compile time에 값이 저장되는 ‘r2’, ‘r3’, ‘r4’와는 다르게 r1은 run time에 값이 정해지기 때문에 constant ‘res’의 주소값을 받아오지 않는 것 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import dis


def F():
    with open("ex.txt", 'r') as f:
        r1 = f.read()
    # r1 = input()  # 결과는 동일
    r2 = 'res'
    r3 = 'res'
    
    a = r1 is r2
    b = r1 == r2
    
    return a, b

dis.dis(F)
  4           0 LOAD_GLOBAL              0 (open)
              2 LOAD_CONST               1 ('ex.txt')
              4 LOAD_CONST               2 ('r')
              6 CALL_FUNCTION            2
              8 SETUP_WITH              14 (to 24)
             10 STORE_FAST               0 (f)

  5          12 LOAD_FAST                0 (f)
             14 LOAD_METHOD              1 (read)
             16 CALL_METHOD              0
             18 STORE_FAST               1 (r1)
             20 POP_BLOCK
             22 LOAD_CONST               0 (None)
        >>   24 WITH_CLEANUP_START
             26 WITH_CLEANUP_FINISH
             28 END_FINALLY

  6          30 LOAD_CONST               3 ('res')
             32 STORE_FAST               2 (r2)

  7          34 LOAD_CONST               3 ('res')
             36 STORE_FAST               3 (r3)

  9          38 LOAD_FAST                1 (r1)
             40 LOAD_FAST                2 (r2)
             42 COMPARE_OP               8 (is)
             44 STORE_FAST               4 (a)

 10          46 LOAD_FAST                1 (r1)
             48 LOAD_FAST                2 (r2)
             50 COMPARE_OP               2 (==)
             52 STORE_FAST               5 (b)

 12          54 LOAD_FAST                4 (a)
             56 LOAD_FAST                5 (b)
             58 BUILD_TUPLE              2
             60 RETURN_VALUE