Ada apa dengan cache integer yang dikekalkan oleh penterjemah?
Selepas meneroka kod sumber Python, saya menemui tatasusunan PyInt_Objects yang dikekalkan, dari int(- 5) kepada int(256) (@src/Objects/intobject.c).
Menjalankan ujian kecil membuktikannya:
>>> a = 1 >>> b = 1 >>> a is b True >>> a = 257 >>> b = 257 >>> a is b False
Walau bagaimanapun, apabila menjalankan arahan ini bersama-sama dalam fail py atau menyertai mereka dengan koma bertitik, hasilnya berubah:
>>> a = 257; b = 257; a is b True
Untuk memahami mengapa kedua-duanya integer masih merujuk objek yang sama, saya menyelidiki pokok sintaks dan pengkompil dan menjumpai hierarki panggilan berikut:
PyRun_FileExFlags() mod = PyParser_ASTFromFile() node *n = PyParser_ParseFileFlagsEx() //source to cst parsetoke() ps = PyParser_New() for (;;) PyTokenizer_Get() PyParser_AddToken(ps, ...) mod = PyAST_FromNode(n, ...) //cst to ast run_mod(mod, ...) co = PyAST_Compile(mod, ...) //ast to CFG PyFuture_FromAST() PySymtable_Build() co = compiler_mod() PyEval_EvalCode(co, ...) PyEval_EvalCodeEx()
Saya kemudiannya menyepadukan kod nyahpepijat ke dalam PyInt_FromLong dan sebelum/selepas PyAST_FromNode , kemudian menjalankan test.py skrip:
a = 257 b = 257 print "id(a) = %d, id(b) = %d" % (id(a), id(b))
Outputnya ialah:
DEBUG: before PyAST_FromNode name = a ival = 257, id = 176046536 name = b ival = 257, id = 176046752 name = a name = b DEBUG: after PyAST_FromNode run_mod PyAST_Compile ok id(a) = 176046536, id(b) = 176046536 Eval ok
Ini menunjukkan bahawa dua PyInt_Objects berasingan dijana semasa transformasi cst ke ast (dilaksanakan dalam ast_for_atom()); namun, objek ini kemudiannya digabungkan.
Saya mendapati kod sumber dalam PyAST_Compile dan PyEval_EvalCode sukar difahami, jadi saya meminta bantuan. Bolehkah seseorang menawarkan sebarang cerapan?
Atas ialah kandungan terperinci Mengapa Kelakuan Cache Integer Python Berubah Bergantung pada Cara Kod Dilaksanakan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!