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

3 投票
2 回答
1505 浏览
提问于 2025-04-18 09:47

我创建了一个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),这样其他人可以通过在工具目录中添加自己的文件来扩展这个应用。实现这个目标的方法是让他们继承我创建的一个类。例如,以下是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 个回答

0
import multitool

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

导入一个包并不会自动导入它里面的子包和子模块。你可以试试这个:

import multitool.core.classes

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

首先,当你安装这个包时,你引入了核心部分,但没有说明它是多工具包的一部分。所以:

import core

应该是这样的:

from multitool import core

这样解释器就知道要从哪个模块引入核心部分。

[编辑]

关于已安装包的目录结构,脚本需要放在一个与模块不同的目录里。按照显示的目录结构,Distutils会把你命名的脚本安装到系统查找可执行文件的地方,同时也会放在包里面,这可能就是造成混淆的原因。

撰写回答