いいえ、ありません。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
ご覧のとおり、__len__
属性は毎回検索され、呼び出されます。
Python は、特定のメソッドが呼び出し間で何を返すかを知ることができません__len__
。メソッドも例外ではありません。Python が呼び出し間で返される値が同じであると想定して最適化しようとすると、数え切れないほどのさまざまな問題に遭遇することになり、マルチスレッドの使用はまだ試していません。
フックを直接len(myList)
呼び出さずに、を使用する方がはるかに良いことに注意してください。__len__()
print len(myList)
for i in xrange(len(myList):
print i + len(myList)