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

问题描述:

我创建了一个具有以下目录结构的 Python 包:

I have created a Python package with the following directory structure:

/
 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),第 3 方可以通过将他们自己的文件添加到工具目录来添加该应用程序.这是通过让他们对我创建的类进行子类化来实现的.例如,这些是 hashtool.py 的前几行:

The goal is to create a command line application (multitool.py) that 3rd parties can add to by adding their own files to the tools directory. This is accomplished by having them subclass a class that I've created. For example, these are the first few lines of hashtool.py:

import multitool

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

只要我从项目目录本身运行它,所有这些都可以工作:

All of this works as long as I run it from the project directory itself:

$ ./multitool.py -h             <---works
$ ./multitool/multitool.py -h   <---works

当我尝试将其创建为包并将其安装时,问题就出现了.安装运行并安装脚本.但是,当您运行脚本时,它找不到包中的任何模块:

The problem comes when I try to create and install it as a package. The install runs and installs the script. However, when you run the script, it cannot find any of the modules in the package:

$ multitool.py

import core 

ImportError: No module named core

我已尝试将导入更改为 multitool、multitool.core、.multitool、..multitool 和其他具有相同结果的文件.

I've tried changing the import to multitool, multitool.core, .multitool, ..multitool, and others with the same result.

但是,我能够从 Python 解释器中进行导入:

However, I am able to do imports from the Python interpreter:

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

这是我的 setup.py 的相关部分

Here is the relevant portion of my setup.py

setup(
    name = 'multitool',
    version = __version__,
    license = 'GPLv2',
    packages = find_packages(exclude=['test/']),
    scripts = ['multitool/multitool.py'],
    include_package_data = True,
    ....
)

我做错了什么?如何从与包一起安装的脚本中的工具目录中导入我自己的代码和文件?

What am I doing wrong? How can I import my own code and the files from the tools directory in the script that I install with the package?

已更新MrAlias 在下面编辑的评论有效.令人困惑的是脚本与包本身同名,并且不在单独的目录中.将脚本移动到它自己的 bin/目录解决了这个问题.

Updated MrAlias's edited comment below worked. The confusion was that the script was the same name as the package itself and was not in a separate directory. Moving the script to its own bin/ directory solved the problem.

首先,当您安装软件包时,您正在导入核心,而没有确定它是 multitool 软件包的一部分.所以:

First off, when you install the package you are importing core without identifying it is being apart of the multitool package. So:

import core

应该是,

from multitool import core

这样解释器就知道要从中导入核心的模块.

That way the interpreter knows the module to import core from.

至于安装包的目录结构,脚本需要进入与模块本身不同的目录.显示的目录结构方式 Distutils 会将您命名的脚本安装到您​​的系统查找可执行文件的位置以及包本身中,这可能是所有混淆的来源.

As for the directory structure of the installed package, scripts need to go into a separate directory from the module itself. The way the shown directory structure is Distutils will install the script you named into both a place your system looks for executables as well as in the package itself, which is likely where all the confusion is coming from.