导入没有.py扩展名的python模块

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了导入没有.py扩展名的python模块相关的知识,希望对你有一定的参考价值。

我有一个名为foobar的文件(没有.py扩展名)。在同一目录中,我有另一个尝试导入它的python文件:

import foobar

但这只有在我将文件重命名为foobar.py时才有效。是否可以导入没有.py扩展名的python模块?

更新:该文件没有扩展名,因为我也将它用作独立脚本,我不想输入.py扩展名来运行它。

Update2:我将选择下面提到的符号链接解决方案。

答案

您可以使用imp.load_source函数(来自imp模块)从给定的文件系统路径动态加载模块。

foobar = imp.load_source('foobar', '/path/to/foobar')

这个SO discussion也展示了一些有趣的选择。

另一答案

像其他人提到的那样,您可以使用imp.load_source,但它会使您的代码更难以阅读。如果您需要导入直到运行时才知道其名称或路径的模块,我真的只会推荐它。

你不想使用.py扩展名的原因是什么?不想使用.py扩展名的最常见情况是因为python脚本也作为可执行文件运行,但您仍然希望其他模块能够导入它。如果是这种情况,将功能移动到具有类似名称的.py文件中可能是有益的,然后使用foobar作为包装器。

另一答案

imp.load_source(module_name, path)应该做,或者你可以做更详细的imp.load_module(module_name, file_handle, ...)路线,如果你有一个文件句柄而不是

另一答案

这是Python 3.4+的解决方案:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("foobar", SourceFileLoader("foobar", "/path/to/foobar"))
foobar = module_from_spec(spec)
spec.loader.exec_module(foobar)

使用spec_from_loader并明确指定SourceFileLoader将强制machinery将文件作为源加载,而不试图从扩展名中找出文件的类型。这意味着您可以加载文件,即使它未在importlib.machinery.SOURCE_SUFFIXES中列出。

如果要在第一次加载后按名称继续导入文件,请将模块添加到sys.modules

sys.modules['foobar'] = foobar
另一答案

如果您使用包管理器(deb或类似)安装脚本,则另一个选项是使用setuptools:

“...没有简单的方法让脚本的文件名与Windows和POSIX平台上的本地约定相匹配。另一方面,当你的实际”主“是一个时,你经常需要为”主“脚本创建一个单独的文件。在某个模块中运行的函数... setuptools通过使用正确的扩展名为您自动生成脚本来修复所有这些问题,并且在Windows上它甚至会创建一个.exe文件...“

https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation

以上是关于导入没有.py扩展名的python模块的主要内容,如果未能解决你的问题,请参考以下文章

python 模块的概念介绍

python之基础篇——模块与包

Python 之 模块

模块的导入

15模块

浅析 Python 模块