安装的Python脚本无法导入包模块

3

我创建了一个Python包,其目录结构如下:

/
 LICENSE
 MANIFEST.IN
 README.rst
 VERSION
 docs/
 multitool/
     __init__.py
     core/
         __init__.py
         classes.py
         utils.py
     libs/
     multitool.py
     tests/
     tools/
         __init__.py
         hashtool.py
         webtool.py
 setup.py

目标是创建一个命令行应用程序(multitool.py),第三方可以通过将自己的文件添加到tools目录中来添加功能。这是通过让他们子类化我创建的类来实现的。例如,以下是hashtool.py的前几行:

import multitool

class HashTool(multitool.core.classes.CLITool):

只要我从项目目录中运行它,所有这些都可以正常工作:
$ ./multitool.py -h             <---works
$ ./multitool/multitool.py -h   <---works

问题出现在我试图将其作为包创建和安装时。安装运行并安装脚本。然而,当你运行脚本时,它无法找到包中的任何模块。
$ multitool.py

import core 

ImportError: No module named core

我尝试将导入更改为multitool、multitool.core、.multitool、..multitool和其他选项,但结果都一样。

然而,我确实能够从Python解释器进行导入:

Type "help", "copyright", "credits" or "license" for more information.
>>> import multitool
>>> import multitool.core
>>> import multitool.core.classes
>>> from multitool import core
>>> 

这是我的setup.py的相关部分:
setup(
    name = 'multitool',
    version = __version__,
    license = 'GPLv2',
    packages = find_packages(exclude=['test/']),
    scripts = ['multitool/multitool.py'],
    include_package_data = True,
    ....
)

我做错了什么?我应该如何在安装包中的脚本中导入自己的代码和工具目录中的文件?请参考下方MrAlias编辑的留言。混淆之处在于脚本与包本身同名且未在单独的目录中。将脚本移动到自己的bin/目录中即可解决问题。
2个回答

4

首先,在安装包时,您导入了core,但没有指定它是多功能工具包中的一部分。因此:

import core

应该是,

from multitool import core

这样解释器就知道从哪个模块中导入“core”。

[编辑]

对于已安装软件包的目录结构,脚本需要放在一个与模块本身不同的目录中。展示的目录结构方式是Distutils将你命名的脚本安装到系统寻找可执行文件的位置以及包本身中,这很可能是造成所有混乱的原因。


谢谢。我刚刚再次尝试了一下,但是又出现了另一个 ImportError: cannot import name core 的错误。 - doza
你的site-packages目录结构是什么样的?并且你是在虚拟环境中运行吗? - MrAlias
是的,这是在virtualenv中运行的。仅从脚本中打印dir(multitool)只显示了脚本自身中的声明,而不是包中的声明。即multitool.main()被显示,但multitool.core没有。我刚刚尝试将multitool.py移动到bin/mtcl.py,现在我可以从脚本中运行"from multitool import core, libs"。现在一切似乎都正常工作了,所以我很高兴,但我想我不明白为什么它以前不能工作。 - doza

0
import multitool

class HashTool(multitool.core.classes.CLITool):

导入一个包并不会导入它的子包和子模块。请尝试这样做:

import multitool.core.classes

class HashTool(multitool.core.classes.CLITool):

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接