我用C ++编写了一个Python模块,并将其构建为共享对象库,并且工作正常。但是在解决所有这些问题时,我注意到(通过strace)Python会查找一些不同的变体import
。特别是,当我说import foo
时,Python按顺序搜索:
除了foomodule.so之外,这一切都是可以理解的。为什么Python会以name.so和namemodule.so的形式查找所有内容?这是一些历史文物吗?我搜索了很多,根本没有解释,我想知道我是否应该命名我的模块foomodule.so而不是foo.so.我的系统似乎在每个约定之后都有一些现有的Python模块,所以我不禁想知道不同的名字是否意味着什么。
答案 0 :(得分: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年开始实现了这一变化,显然将“module.so”添加为可能的后缀:http://hg.python.org/cpython-fullhistory/diff/8efa37a770c6/Python/importdl.c。因此,最初为NeXTStep(最终成为Mac OS X的那个)添加了更改,仅针对特定的链接设置。我不知道这个操作系统所以很难说它为什么会这样做 - 我怀疑它只是为了防止命名冲突。例如。可能已加载框架库 foo.so
,操作系统将不允许加载另一个具有相同名称的库。所以foomodule.so
是允许名称为foo
的Python模块存在的妥协。
编辑:上面的段落错了 - 我在历史上没有做得足够多,感谢发送者指出了这一点。事实上,从1994年开始,有趣的变化似乎是http://hg.python.org/cpython-fullhistory/diff/2230/Python/import.c,这是新模块命名方案(foo.so
)被添加为旧方案(foomodule.so
)的替代方案。我猜这个旧表格在某些时候已经被弃用了,因为对于某些平台,例如Windows中的一个平台,在该代码的众多重写之一中已经删除了对它的支持。请注意,即使首次引入,也会首先列出短模块名称版本 - 这意味着它已经是首选变体。
Edit2 :我从1994年搜索了邮件列表/新闻组,看看这个变化是否在某个地方被讨论过 - 看起来不像是这样,Guido van Rossum似乎已经实现了它而没有告诉任何人
答案 1 :(得分:10)
这只是猜测,但我只能假设这与下面的Extending Python with C or C++相关。
首先创建一个文件spammodule.c。 (从历史上看,如果模块被称为垃圾邮件,则包含其实现的C文件称为spammodule.c;如果模块名称非常长,如spammify,则模块名称可能只是spammify.c。)
我认为这个约定扩展到.so
文件的名称。 the same的第1.5节进一步支持了这一猜想。
根据Wladimir的excellent discovery,我发现first reference到module.so
作为后缀。它来自一个补丁,支持动态加载SunOS库,来自“Bill”。 (Bill Jansson?)显然,module
- as-suffix约定在使用.so
共享库之前开始,并且当采用.so
库时,简单地维护了约定。 / p>
我认为弗拉迪米尔是正确的 - 有趣的变化是采用短模块名称惯例的变化。这证实了我的猜测,长模块名称是早期的惯例。