2011-06-12 45 views
19

我已經在C++中編寫了一個Python模塊並將其構建爲共享對象庫,並且它工作正常。但在確定所有這一切時,我注意到(通過strace)Python尋找幾個不同的變體import被調用。特別是,當我說import foo,Python的搜索,依次是:Python共享對象模塊命名約定

  • 富(目錄)
  • foo.so
  • foomodule.so
  • foo.py
  • foo.pyc

除了foomodule.so,這是非常容易理解的。爲什麼Python將所有內容都作爲name.so和namemodule.so來查找?這是否是一些歷史神器?我搜索了很多,並沒有提出任何解釋,我還想知道是否應該命名我的模塊foomodule.so而不是foo.so.我的系統似乎在每個約定之後都有一些現有的Python模塊,所以我不禁要問,不同的名稱是否意味着某種東西。

回答

18

這實際上是依賴於平臺的,Python有不同的後綴,它會根據操作系統進行嘗試。下面是後綴表的import.c初始化:

#ifdef HAVE_DYNAMIC_LOADING 
    memcpy(filetab, _PyImport_DynLoadFiletab, 
      countD * sizeof(struct filedescr)); 
#endif 
    memcpy(filetab + countD, _PyImport_StandardFiletab, 
      countS * sizeof(struct filedescr)); 
    filetab[countD + countS].suffix = NULL; 

    _PyImport_Filetab = filetab; 

,以連接兩個列表,_PyImport_DynLoadFiletab_PyImport_StandardFiletab。後者更容易,它在同一個文件中被定義爲[".py", ".pyw", ".pyc"](第二個條目僅存在於Windows上)。 _PyImport_DynLoadFiletab在各種dynload_<platform>.c文件中定義。在基於Unix的系統上,其值爲[".so", "module.so"],對於CygWin,它定義爲[".dll", "module.dll"],而對於OS/2,其值爲[".pyd", ".dll"],對於Windows,它僅是[".pyd"]

我經歷了源​​代碼的歷史,終於從1999年開始了這個明顯增加了「模塊」的變化。所以「作爲可能的後綴:http://hg.python.org/cpython-fullhistory/diff/8efa37a770c6/Python/importdl.c。所以這些改變最初是爲NeXTStep(最終成爲Mac OS X的)添加的,僅用於特定的鏈接設置。我不知道這個操作系統,因此很難說出它爲什麼是完成 - 我懷疑這只是爲了防止命名衝突,例如一個框架庫foo.so可能已經加載,操作系統將不允許加載另一個相同名稱的庫,因此foomodule.so是一個折衷方案,允許使用名稱的Python模塊foo到儘管如此存在

編輯:。以上是錯的一段 - 我沒有走得足夠遠回顧歷史,得益於senderle指出了這一點事實上,有趣的變化似乎是http://hg.python.org/cpython-fullhistory/diff/2230/Python/import.c從1994年h是添加新模塊命名方案(foo.so)作爲舊方案(foomodule.so)的替代方案。我猜舊格式在某些時候已被棄用,因爲在該代碼的許多重寫之一中,對於Windows等某些平臺的支持已被刪除。請注意,即使在首次推出時,短模塊名稱版本也首先列出 - 這意味着它已經是首選變體。我從1994年開始搜索郵件列表/新聞組,看看這個變化是否在某個地方被討論過 - 看起來並不像這樣,Guido van Rossum似乎在沒有告訴任何人的情況下實現了它。

+0

有趣,我不知道那個完整的歷史瀏覽器。那裏有一些深層的機構記憶。然而,定義'#define LONG_EXT「module.so」' - 如果這就是你所指的 - 在你正在討論的補丁早有很長時間了。事實上,當['importdl.c'](http://hg.python.org/cpython-fullhistory/file/d7e91437f0a2/Python/importdl.c)首次創建時,它就在那裏! – senderle 2011-06-30 14:50:25

+0

@senderle:謝謝,我確實犯了一個錯誤。 'importdl.c'是在重寫中創建的,原始代碼可以在'import.c'中找到 - 我發現引入了兩個命名方案並更新了我的答案的更改。太糟糕了,Pythons的機構記憶不包括導致變化的討論。 – 2011-06-30 15:07:12

10

這只是一個猜測,但我只能假設這與下面的Extending Python with C or C++有關。

首先創建一個文件spammodule.c。 (從歷史上看,如果一個模塊被稱爲垃圾郵件,包含其執行的C文件名爲spammodule.c;如果模塊名稱很長,像spammify,模塊名稱可以只是spammify.c。)

我想這個約定擴展到.so文件的名字。 the same的第1.5節進一步支持該推測。


基於弗拉基米爾的excellent discovery,我已經找到了first referencemodule.so作爲後綴。它來自支持動態加載SunOS庫的補丁,來自「Bill」。 (Bill Jansson?)顯然module -as-suffix約定在使用共享庫之前就開始了,並且當採用.so庫時,約定被簡單地維護了。

我認爲弗拉基米爾是正確的 - 有趣的變化是採用短模塊名稱約定。這證實了我的猜測,即長模塊名稱是早期的慣例。

+1

我回去檢查了Python查找各種文件的順序。我注意到它在foomodule.so之前查找foo.so,如果foomodule.so是首選形式,這看起來很奇怪。我會等待其他人加入,因爲雖然我覺得你的回答合理,但也有點手搖(沒有冒犯,我想我仍然在尋找一些消息來源說「這就是爲什麼我們有兩種模式」或類似的東西)。 – 2011-06-12 00:53:28

+0

是的,毫無疑問,這是手工波浪:)。但對我來說似乎很清楚,一定有一個早期的'foomodule'慣例不再受歡迎,但由於某種原因很難驅邪。我也有興趣聽到這位老前輩關於這個問題的消息。 – senderle 2011-06-12 05:13:10

+0

即使在添加'module.so'之前,Python已經加載了帶有'module.o'文件名後綴的模塊 - 您鏈接的更改僅僅增加了對SunOS的支持。添加了對動態加載支持的補丁程序是http://hg.python.org/cpython-fullhistory/diff/609/Python/import.c,它已經使用'module.o'作爲後綴 - 我想這是遵循Amoeba's命名約定。 – 2011-06-30 15:58:38