Joh*_*nck 19 python module naming-conventions shared-libraries
我用C++编写了一个Python模块,并将其构建为共享对象库,并且工作正常.但是在计算出所有这些的同时,我注意到(通过strace)Python会查找一些不同的变体import.特别是,当我说import foo,Python按顺序搜索:
除了foomodule.so之外,这一切都是可以理解的.为什么Python会以name.so和namemodule.so的形式查找所有内容?这是一些历史文物吗?我搜索了很多,根本没有解释,我想知道我是否应该命名我的模块foomodule.so而不是foo.so. 我的系统似乎在每个约定之后都有一些现有的Python模块,所以我不禁想知道不同的名字是否意味着什么.
Wla*_*ant 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;
Run Code Online (Sandbox Code Playgroud)
所以它加入了两个列表,_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,允许具有名称的Python模块foo存在的妥协也是如此.
编辑:上面的段落是错误的 - 我在历史上没有走得太远,多亏了发送者指出了这一点.事实上,有趣的变化似乎是从1994年开始的http://hg.python.org/cpython-fullhistory/diff/2230/Python/import.c,这是一个新的模块命名方案(foo.so)被添加为替代旧计划(foomodule.so).我猜这个旧表格在某些时候已经被弃用,因为对于某些平台,例如Windows中的一个平台,在该代码的众多重写之一中已经删除了对它的支持.请注意,即使首次引入,也会首先列出短模块名称版本 - 这意味着它已经是首选变体.
Edit2:我从1994年开始搜索邮件列表/新闻组,看看这个变化是否在某个地方被讨论过 - 看起来不像是这样,Guido van Rossum似乎已经实现了它而没有告诉任何人.
sen*_*rle 10
这只是一个猜测,但我只能假设这与下面的相关,来自使用C或C++扩展Python.
首先创建一个文件spammodule.c.(从历史上看,如果模块被称为垃圾邮件,则包含其实现的C文件称为spammodule.c;如果模块名称非常长,如spammify,则模块名称可能只是spammify.c.)
我想这个约定扩展到.so文件的名称.这推测是由第1.5节进一步支持相同.
基于弗拉基米尔的优秀发现,我已经找到了第一个参考,以module.so作为后缀.它来自一个补丁,支持动态加载SunOS库,来自"Bill".(Bill Jansson?)显然,module-as-suffix约定在使用.so共享库之前开始,当采用库时.so,简单地保留了约定.
我认为弗拉迪米尔是正确的 - 有趣的变化是采用短模块名称约定的变化.这证实了我的猜测,长模块名称是早期的惯例.