Ponieważ ciąg jest niezmienny (tak jak krotka), jest przechowywany z obiektem kodu bajtowego dla tej funkcji. Jest ładowany przez bardzo proste i szybkie wyszukiwanie indeksu. Jest to faktycznie szybsze niż wyszukiwanie globalne.
Można to zobaczyć w demontażu kodu bajtowego, za pomocą dis.dis()
function:
>>> import dis
>>> def foo(s):
... c_string = "hello"
... if s == c_string:
... return True
... return False
...
>>> dis.dis(foo)
2 0 LOAD_CONST 1 ('hello')
3 STORE_FAST 1 (c_string)
3 6 LOAD_FAST 0 (s)
9 LOAD_FAST 1 (c_string)
12 COMPARE_OP 2 (==)
15 POP_JUMP_IF_FALSE 22
4 18 LOAD_GLOBAL 0 (True)
21 RETURN_VALUE
5 >> 22 LOAD_GLOBAL 1 (False)
25 RETURN_VALUE
>>> foo.__code__.co_consts
(None, 'hello')
LOAD_CONST
opcode ładuje obiektu String z tablicy co_costs
który jest częścią przedmiotu kod funkcji; odniesienie jest wypychane na wierzch stosu. Kod operacyjny STORE_FAST
pobiera odniesienie od góry stosu i zapisuje je w tablicy miejscowej, ponownie bardzo prostą i szybką operację.
Do modyfikowalnych literałów ({..}
, [..]
) specjalne rozkazy zbudować obiekt, o zawartości nadal traktowane jako stałe jak to możliwe (bardziej złożonych struktur prostu wykonaj te same bloki):
>>> def bar(): return ['spam', 'eggs']
...
>>> dis.dis(bar)
1 0 LOAD_CONST 1 ('spam')
3 LOAD_CONST 2 ('eggs')
6 BUILD_LIST 2
9 RETURN_VALUE
BUILD_LIST
call tworzy nowy obiekt listy, używając dwóch stałych obiektów napisowych.
Interesujący fakt: Jeśli użyłeś obiektu listy do testu członkostwa (something in ['option1', 'option2', 'option3']
Python wie, że obiekt listy nigdy nie zostanie zmutowany i przekonwertuje go na krotkę dla Ciebie podczas kompilacji (tak zwana optymalizacja peephole). to samo odnosi się do zestawu dosłownym, który jest przekształcany w frozenset()
obiektu, ale tylko w Pythonie 3.2 i nowszym Zobacz Tuple or list when using 'in' in an 'if' clause?
pamiętać, że funkcja próbkę za pomocą wartości logicznych raczej --long; może po prostu wykorzystali.
def foo(s):
c_string = "hello"
return s == c_string
dla dokładnie tego samego wyniku, unikając LOAD_GLOBAL
wywołania w Python 2 (Python 3 wykonane True
i False
słów kluczowych, więc wartości mogą być również przechowywane jako stałe).
Czy to samo nie dzieje się z 's ==" cześć "? – jonrsharpe
Masz rację co do komentarza dotyczącego krotek, powinienem raczej zapytać o listę. Znowu poprawię pytanie. Reszta odpowiedzi na razie jest znakomita :) –
@ArthurVaiselbuh: Ja również opisywałem listy, jak również słowniki i zestawy '{...}. –