8

下面是試圖初始化一個空sys.path解釋一個CPython的程序:運行Python 3.5解釋器需要哪些標準庫模塊?

#include <Python.h> 

int main(int argc, char** argv) 
{ 
    wchar_t* program = NULL; 
    wchar_t* sys_path = NULL; 

    Py_NoSiteFlag = 1; 

    program = Py_DecodeLocale(argv[0], NULL); 
    Py_SetProgramName(program); 

    sys_path = Py_DecodeLocale("", NULL); 
    Py_SetPath(sys_path); 

    Py_Initialize(); 

    PyMem_RawFree(program);  
    PyMem_RawFree(sys_path); 
    Py_Finalize(); 
} 

執行上述計劃引發了以下錯誤:

Fatal Python error: Py_Initialize: Unable to get the locale encoding 
ImportError: No module named 'encodings' 

Current thread 0x00007ffff7fc6700 (most recent call first): 
Signal: SIGABRT (Aborted) 

所以它在Python包和模塊3.5標準庫除了encodings包以外,絕對需要運行Python 3.5解釋器嗎?這些信息對我來說似乎在文檔中是沒有的。

+0

您可以通過運行解釋器然後查看導入模塊的字典來查看它包含的內容。 –

回答

6

這些是在翻譯啓動過程中使用的軟件包/模塊(如@Charles Duffy在評論中指出的,通過查看sys.modules)。

結果取決於您是否啓用了site(您的Py_NoSiteFlag = 1;意味着情況並非如此,但無論如何,我會給出兩個選項:-))。

site拖動了幾個與它額外的模塊,當你使用它像_sitebuiltinsstat,總共你只能使用Python運行以下命令:

abc.py    encodings  os.py   _sitebuiltins.py sysconfig.py 
codecs.py   genericpath.py posixpath.py site.py   _collections_abc.py 
io.py    stat.py   _weakrefset.py 

site禁用,你剝離下來以下6

abc.py codecs.py encodings io.py os.py _weakrefset.py 

Py_Initialize()(或通過Windows根據您的評論)通過C時調用我估計os.py可能實際上並不需要。

+0

* build *是什麼意思?我可以在'sys.path'中使用'encodings'軟件包,'_weakrefset','abc','codecs'和'io'模塊來運行解釋器。 – Jovito

+0

這些可以做的事情並不多,但依然如此。 – Jovito

+0

啊,我認爲你的意思是關於整個過程(即獲得CPython的源代碼,構建它,然後*運行它)。是的,對於簡單地運行解釋器,您需要我列出的模塊/軟件包的一小部分。既然你已經找到了所需的模塊,我想你已經回答了你自己的問題:-) @Jovito –

1

如果您按Charles Duffy在他的評論中建議的方式運行解釋器,則會加載像readline這樣的包。自從我這樣做以來已經有十年了,但是如果您使用python作爲C程序的擴展,IIRC不需要該模塊,因爲沒有命令行交互。其他模塊可能也是如此。

確定真正需要的東西的最快方法只有一點點得到太多的機會,把所有的lib/python3.5放到你的程序可以找到它的地方,然後在程序中打印出sys.modules,給你一個你的程序實際加載的列表,而不是解釋器可能需要啓動的東西。之後,刪除不在列表中的所有內容。

1

這裏的另一種方法 - 要求Python解釋器模塊被加載的內容:

$ python3.5 -v -S -c '' |& grep SourceFileLoader | sort 
import 'abc' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e860> 
import '_bootlocale' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d1367b8> 
import 'codecs' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d187fd0> 
import 'encodings.aliases' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d11eac8> 
import 'encodings' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d187be0> 
import 'encodings.latin_1' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e3c8> 
import 'encodings.utf_8' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12c898> 
import 'io' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d12e5f8> 
import '_weakrefset' # <_frozen_importlib_external.SourceFileLoader object at 0x7f4b1d135080> 

_bootlocale不是必需的,但建議。它用於初始化sys.stdin/sys.stdout/sys.stderr的最佳編碼。見https://hg.python.org/cpython/rev/fbbf8b160e8d

sys.modules可以說謊,因爲它是可變的。