导入没有.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模块的主要内容,如果未能解决你的问题,请参考以下文章