解釋器維護的整數快取是怎麼回事?
在探索 Python 的源代碼後,我發現了一個維護的 PyInt_Object 數組,範圍從 int(- 5) 到 int(256) (@src/Objects/intobject.c).
運行一個小測試證明了這一點:
>>> a = 1 >>> b = 1 >>> a is b True >>> a = 257 >>> b = 257 >>> a is b False
但是,當在 py文件中一起執行這些命令時或用分號連接它們,結果更改:
>>> a = 257; b = 257; a is b True
為了理解為什麼這兩個整數仍然引用同一個對象,我深入研究了語法樹和編譯器,並發現了以下呼叫層次結構:
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()
然後我將偵錯程式碼整合到PyInt_FromLong 和PyAST_FromNode 之前/之後,然後運行test.py 腳本:
a = 257 b = 257 print "id(a) = %d, id(b) = %d" % (id(a), id(b))
輸出為:
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
這表明在cst 期間產生了兩個單獨的PyInt_Object到ast 轉換(在ast_for_atom() 中執行);
我發現 PyAST_Compile 和 PyEval_EvalCode 中的原始程式碼難以理解,因此我尋求協助。有人可以提供任何見解嗎?
以上是為什麼 Python 的整數快取行為會根據程式碼的執行方式而改變?的詳細內容。更多資訊請關注PHP中文網其他相關文章!