Należy wziąć pod uwagę następującą funkcję.
def f(x):
x += n
return x * 4
Tutaj x
jest nazwą lokalną, jej wartość może się zmienić. 4
jest stałą. Jego wartość nigdy się nie zmieni. Jednak nadal jest to obiekt i lepiej jest je buforować niż tworzyć nowy obiekt za każdym razem, gdy jest potrzebny. Wreszcie, n
jest globalnym odniesieniem. Ciąg "n"
jest przechowywany przez funkcję, dzięki czemu można go użyć jako klucza do pobrania n
z globalnego kontekstu funkcji.
>>> f.__code__.co_nlocals # just 1 (for x)
1
>>> f.__code__.co_consts
(None, 4)
>>> f.__code__.co_names
('n',)
>>> "n" in f.__globals__ and globals() is f.__globals__
True
Powód oddzielenia nazw i stałych jest dla celów introspekcji. Jedynym prawdziwym powodem do scalenia krotek byłaby wydajność pamięci, ale to tylko zyskałoby jeden obiekt i jeden wskaźnik na funkcję. Rozważ następującą funkcję.
def g():
return "s" * n
Jeśli krotka zawierająca consts została połączona z nazwiskami krotka zawierająca wtedy (nie VM) nie będzie w stanie powiedzieć, jakie wartości były dostępu do globalnych i które były stałe funkcji.
Aby sprawdzić, czy mówisz o poprawnym cpythonie? Która wersja? –
@GamesBrainiac: 'co_names' jest używane w cpythonie zarówno 2 jak i 3 oraz w pypy. Nie jestem pewien innych implementacji, ponieważ ich nie używam. – 6502
Nie pamiętam wszystkiego dobrze, ale jestem prawie pewien, że ma to coś wspólnego z marynowaniem. –