保存我多次使用的列表的长度是否更好?

mth*_*pvg 2 python list

我知道内联,并且从我检查它不是由Python的编译器完成的.

我的问题是:python的编译器是否有任何优化转换:

print myList.__len__()
for i in range(0, myList.__len__()):
    print i + myList.__len__()
Run Code Online (Sandbox Code Playgroud)

l = myList.__len__()
print l
for i in range(0, l):
    print i + l
Run Code Online (Sandbox Code Playgroud)

它是由编译器完成的吗?
如果不是:我自己这样做是否值得?

奖金问题(不是那么相关):我喜欢有很多功能(更好的可读性恕我直言)...就像在Python中没有内联这是要避免的东西(很多功能)?

Mar*_*ers 6

不,没有.您可以通过使用dis模块将代码编译为字节码来检查Python的功能:

>>> def test():
...     print myList.__len__()
...     for i in range(0, myList.__len__()):
...         print i + myList.__len__()
... 
>>> import dis
>>> dis.dis(test)
  2           0 LOAD_GLOBAL              0 (myList)
              3 LOAD_ATTR                1 (__len__)
              6 CALL_FUNCTION            0
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  3          11 SETUP_LOOP              44 (to 58)
             14 LOAD_GLOBAL              2 (range)
             17 LOAD_CONST               1 (0)
             20 LOAD_GLOBAL              0 (myList)
             23 LOAD_ATTR                1 (__len__)
             26 CALL_FUNCTION            0
             29 CALL_FUNCTION            2
             32 GET_ITER            
        >>   33 FOR_ITER                21 (to 57)
             36 STORE_FAST               0 (i)

  4          39 LOAD_FAST                0 (i)
             42 LOAD_GLOBAL              0 (myList)
             45 LOAD_ATTR                1 (__len__)
             48 CALL_FUNCTION            0
             51 BINARY_ADD          
             52 PRINT_ITEM          
             53 PRINT_NEWLINE       
             54 JUMP_ABSOLUTE           33
        >>   57 POP_BLOCK           
        >>   58 LOAD_CONST               0 (None)
             61 RETURN_VALUE        
Run Code Online (Sandbox Code Playgroud)

如您所见,__len__每次都会查找并调用该属性.

Python无法知道给定方法在调用之间会返回什么,该__len__方法也不例外.如果python试图通过假设返回的值在调用之间是相同的来优化它,那么你会遇到无数不同的问题,我们甚至还没有尝试使用多线程.

请注意,使用起来会好得多len(myList),而不是__len__()直接调用钩子:

print len(myList)
for i in xrange(len(myList):
    print i + len(myList)
Run Code Online (Sandbox Code Playgroud)