我知道内联,并且从我检查它不是由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中没有内联这是要避免的东西(很多功能)?
不,没有.您可以通过使用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)