A question regarding string instance uniqueness in python

前端 未结 4 1775
一个人的身影
一个人的身影 2020-12-21 08:37

I was trying to figure out which integers python only instantiates once (-6 to 256 it seems), and in the process stumbled on some string behaviour I can\'t see the pattern i

4条回答
  •  无人及你
    2020-12-21 09:16

    in answer to S.Lott's suggestion of examining the byte code:

    import dis
    def moo():
        A = "10000"
        B = "10000"
        C = "100" + "00"
        D = "%i"%10000
        E = str(10000)
        F = str(10000)
        G = "1000"+str(0)
        H = "0".join(("10","00"))
        I = str("10000")
    
        for obj in (A,B,C,D,E,F,G,H, I):
            print obj, id(obj), obj is A
    moo()
    print dis.dis(moo)
    

    yields:

    10000 4968128 True
    10000 4968128 True
    10000 4968128 True
    10000 4968128 True
    10000 2840928 False
    10000 2840896 False
    10000 2840864 False
    10000 2840832 False
    10000 4968128 True
      4           0 LOAD_CONST               1 ('10000')
                  3 STORE_FAST               0 (A)
    
      5           6 LOAD_CONST               1 ('10000')
                  9 STORE_FAST               1 (B)
    
      6          12 LOAD_CONST              10 ('10000')
                 15 STORE_FAST               2 (C)
    
      7          18 LOAD_CONST              11 ('10000')
                 21 STORE_FAST               3 (D)
    
      8          24 LOAD_GLOBAL              0 (str)
                 27 LOAD_CONST               5 (10000)
                 30 CALL_FUNCTION            1
                 33 STORE_FAST               4 (E)
    
      9          36 LOAD_GLOBAL              0 (str)
                 39 LOAD_CONST               5 (10000)
                 42 CALL_FUNCTION            1
                 45 STORE_FAST               5 (F)
    
     10          48 LOAD_CONST               6 ('1000')
                 51 LOAD_GLOBAL              0 (str)
                 54 LOAD_CONST               7 (0)
                 57 CALL_FUNCTION            1
                 60 BINARY_ADD          
                 61 STORE_FAST               6 (G)
    
     11          64 LOAD_CONST               8 ('0')
                 67 LOAD_ATTR                1 (join)
                 70 LOAD_CONST              12 (('10', '00'))
                 73 CALL_FUNCTION            1
                 76 STORE_FAST               7 (H)
    
     12          79 LOAD_GLOBAL              0 (str)
                 82 LOAD_CONST               1 ('10000')
                 85 CALL_FUNCTION            1
                 88 STORE_FAST               8 (I)
    
     14          91 SETUP_LOOP              66 (to 160)
                 94 LOAD_FAST                0 (A)
                 97 LOAD_FAST                1 (B)
                100 LOAD_FAST                2 (C)
                103 LOAD_FAST                3 (D)
                106 LOAD_FAST                4 (E)
                109 LOAD_FAST                5 (F)
                112 LOAD_FAST                6 (G)
                115 LOAD_FAST                7 (H)
                118 LOAD_FAST                8 (I)
                121 BUILD_TUPLE              9
                124 GET_ITER            
            >>  125 FOR_ITER                31 (to 159)
                128 STORE_FAST               9 (obj)
    
     15         131 LOAD_FAST                9 (obj)
                134 PRINT_ITEM          
                135 LOAD_GLOBAL              2 (id)
                138 LOAD_FAST                9 (obj)
                141 CALL_FUNCTION            1
                144 PRINT_ITEM          
                145 LOAD_FAST                9 (obj)
                148 LOAD_FAST                0 (A)
                151 COMPARE_OP               8 (is)
                154 PRINT_ITEM          
                155 PRINT_NEWLINE       
                156 JUMP_ABSOLUTE          125
            >>  159 POP_BLOCK           
            >>  160 LOAD_CONST               0 (None)
                163 RETURN_VALUE        
    

    so it would seem that indeed the compiler understands A-D to mean the same thing, and so it saves memory by only generating it once (as suggested by Alex,Maciej and Greg). (added case I seems to just be str() realising it's trying to make a string from a string, and just passing it through.)

    Thanks everyone, that's a lot clearer now.

提交回复
热议问题