2015-10-24 14 views
6

Czytam https://stackoverflow.com/a/19721096/1661745 i wydaje się, że w CPython zmienne są po prostu nazwami, które są powiązane z referencjami.W jaki sposób nazwy zmiennych są przechowywane i mapowane wewnętrznie?

Istnieje kilka rzeczy dzieje się ze stwierdzeniem, x = 5:

  1. int przedmiot o wartości 5 jest tworzony (lub znalezionego jeśli już istnieje)
  2. nazwa x jest tworzony (lub odrębnie z ostatniego obiektu „x” oznakowane)
  3. licznika odwołań do nowego (lub znalezionego) int obiektu jest wzrosła o 1
  4. nazwa x jest powiązane z obiektem z utworzoną (lub znalezioną) wartością "5" .

Jednak nadal nie jest jasne, w jaki dokładnie sposób zmienne są wdrażane wewnętrznie.

mianowicie:

  1. nazwa X jest tworzony (lub odrębnie z ostatnim obiekcie 'x' znakowanym);

Czy nazwa nie zajmie również miejsca w pamięci? sys.sizeof(x) jest równy sys.sizeof(5) i otrzymuję, że sys.sizeof(x) może zwrócić tylko rozmiar skojarzonego odniesienia, ale jaki jest rozmiar nazwy x?

  1. nazwa x jest związany z obiektem o wartości '5' utworzone (lub znalezionego)

Jak to wdrożony wewnętrznie? Myślę, że na wysokim poziomie można to zrobić przy pomocy dict, gdzie klucz jest nazwą zmiennej (str?), A wartość jest odniesieniem, z którym jest powiązana.

+1

* "W jaki sposób jest to realizowane wewnętrznie?" * - w CPython? Powinieneś przeczytać np. http://nedbatchelder.com/text/names.html dla zrozumienia wysokiego poziomu i przekopiuj odpowiedni kod źródłowy, jeśli naprawdę chcesz zrozumieć odwagę. – jonrsharpe

+0

(Na przykład dla CPython, https://hg.python.org/cpython/file/tip/Python/Python-ast.c#l1336) – jonrsharpe

Odpowiedz

3

myślę na wysokim poziomie, można to zrobić z dict, gdzie kluczem jest nazwa zmiennej (str?), A wartość referencyjna jest to, że wiąże się z.

Tak to działa również wewnętrznie. W języku CPython nazwy zmiennych i obiekty, do których prowadzą, są zwykle przechowywane w słowniku Python; taka sama struktura danych, z której można korzystać podczas pisania kodu Pythona.

Podczas pisania x = 5, nazwa x jest ustawiana jako klucz w słowniku nazw globalnych z 5 jako odpowiednią wartością. Możesz powrócić do tego słownika i sprawdzić go za pomocą funkcji , która podaje zawartość obszaru nazw bieżącego oscyloskopu.

Masz również rację, że nazwa x zajmuje miejsce. Istnieje jako ciąg gdzieś w pamięci i Python utrzymuje odniesienie do niego dla klucza słownika.

Jeśli chcesz zagłębić się w źródło CPython, aby zobaczyć, gdzie x zostanie przypisany do wartości 5, możesz rzucić okiem na ceval.c. Zapisywanie x = 5 powoduje wywołanie kodu operacyjnego LOAD_CONST (aby umieścić liczbę całkowitą 5 na stosie), a także opcode STORE_GLOBAL * (aby ustawić nazwę x jako klucz w słowniku z 5 jako wartością).

Here jest kod na STORE_GLOBAL opcode:

TARGET(STORE_GLOBAL) { 
    PyObject *name = GETITEM(names, oparg); 
    PyObject *v = POP(); 
    int err; 
    err = PyDict_SetItem(f->f_globals, name, v); /* call to update dict */ 
    Py_DECREF(v); 
    if (err != 0) 
     goto error; 
    DISPATCH(); 
} 

Można zobaczyć wywołanie PyDict_SetItem do aktualizacji słownika globalnych.


* Jeśli inspekcji kodu bajtowego generowane przez x = 5 (na przykład przy użyciu dis) można zobaczyć STORE_NAME opcodu używany. Ten kod operacyjny działa w ten sam sposób (patrz: here).

+0

Odkrywanie [tablic symboli] (https://en.wikipedia.org/wiki/Symbol_table) uczyniło to znacznie jaśniejszym. – onepiece

Powiązane problemy