在Python 3.6中使用setuptools打包后发生ModuleNotFoundError

在Python 3.6中使用setuptools打包后发生ModuleNotFoundError,python,python-3.x,setuptools,Python,Python 3.x,Setuptools,我正在尝试使用setuptools从Python3.6应用程序生成一个包。当打包在没有错误的情况下终止时,由setuptools生成的命令行程序无法导入包中的模块。 下面是我的项目的目录树 . ├── MANIFEST.in ├── README.md ├── README.rst ├── contributors.txt ├── setup.cfg ├── setup.py ├── sonicparanoid │ ├── __init__.py │ ├── __pycache__ │

我正在尝试使用setuptools从Python3.6应用程序生成一个包。当打包在没有错误的情况下终止时,由setuptools生成的命令行程序无法导入包中的模块。 下面是我的项目的目录树

.
├── MANIFEST.in
├── README.md
├── README.rst
├── contributors.txt
├── setup.cfg
├── setup.py
├── sonicparanoid
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── inpyranoid.cpython-36.pyc
│   │   ├── length_difference_filter.cpython-36.pyc
│   │   ├── ortholog_detection.cpython-36.pyc
│   │   ├── reads_stats.cpython-36.pyc
│   │   ├── seq_tools.cpython-36.pyc
│   │   ├── sonicparanoid.cpython-36.pyc
│   │   ├── sys_tools.cpython-36.pyc
│   │   └── workers.cpython-36.pyc
│   ├── bin
│   │   └── mmseqs
│   ├── blast_tools.py
│   ├── compile_inpyranoid_c.py
│   ├── compile_mmseqs_parser_c.py
│   ├── config.json
│   ├── example
│   │   ├── test_input
│   │   │   ├── chlamydia_trachomatis
│   │   │   ├── deinococcus_radiodurans
│   │   │   ├── gloeobacter_violaceus
│   │   │   └── thermotoga_maritima
│   │   └── test_output
│   │       └── README.txt
│   ├── inpyranoid.py
│   ├── inpyranoid_c.c
│   ├── inpyranoid_c.cpython-36m-darwin.so
│   ├── inpyranoid_c.pyx
│   ├── length_difference_filter.py
│   ├── mmseqs2_src
│   │   ├── README.txt
│   │   └── mmseqs.tar.gz
│   ├── mmseqs_parser_c.c
│   ├── mmseqs_parser_c.cpython-36m-darwin.so
│   ├── mmseqs_parser_c.pyx
│   ├── mmseqs_parser_cython.py
│   ├── ortholog_detection.py
│   ├── quick_multi_paranoid
│   │   ├── Makefile
│   │   ├── Makefile.in
│   │   ├── config
│   │   ├── dump.cpp
│   │   ├── gen_header.cpp
│   │   ├── hashtable.c
│   │   ├── hashtable.h
│   │   ├── hashtable.o
│   │   ├── hashtable_itr.c
│   │   ├── hashtable_itr.h
│   │   ├── hashtable_private.h
│   │   ├── ortholog.c
│   │   ├── qa.h
│   │   ├── qa1
│   │   ├── qa1.cpp
│   │   ├── qa2
│   │   ├── qa2.cpp
│   │   ├── qp
│   │   ├── qp.c
│   │   └── qps.c
│   ├── reads_stats.py
│   ├── seq_tools.py
│   ├── setup_sonicparanoid.py
│   ├── sonicparanoid.py
│   ├── sys_tools.py
│   ├── test_blast_tools.py
│   ├── test_length_difference_filter.py
│   ├── test_ortholog_detection.py
│   ├── test_reads_stats.py
│   ├── test_seq_tools.py
│   ├── test_sonicparanoid.py
│   ├── test_sys_tools.py
│   └── workers.py
└── user_manual.pdf
如果我运行
python3 sonicpanoid.py
,它可以正常工作,但是如果我使用setuptools创建发行版,每当主程序(sonicpanoid.py)尝试导入包(sonicpanoid)目录中的任何其他.py模块时,我都会收到导入错误

以下是my setup.py的版本:

enter code here
from setuptools import setup, find_packages
from setuptools.extension import Extension
from Cython.Build import cythonize
import numpy

extensions = [
    Extension(
        "sonicparanoid.inpyranoid_c",
        ["sonicparanoid/inpyranoid_c.pyx"],
        include_dirs=[numpy.get_include()],
    ),
    Extension(
        "sonicparanoid.mmseqs_parser_c",
        ["sonicparanoid/mmseqs_parser_c.pyx"],
        include_dirs=[numpy.get_include()],
    ),
]


from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))

# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='sonicparanoid',
    version='0.0.2',  # Required
    description='Whatever',
    long_description=long_description,  # Optional
    url='http://iwasakilab.bs.s.u-tokyo.ac.jp/sonicparanoid/',  # Optional
    author='Me',
    author_email='my@email.com',
    classifiers=[  # Optional
        'Development Status :: 5 - Production/Stable',
        'Environment :: Console',
        'Intended Audience :: Science/Research',
        'Topic :: Scientific/Engineering :: Bio-Informatics',
        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
    ],
    packages = ['sonicparanoid',], # Required
    install_requires=['numpy>=1.14.0', 'pandas>=0.22.0', 'cython>=0.27.0',     'sh>=1.12.14', 'setuptools>=24.2.0'], # specify minimum version
    python_requires='>=3.5, <3.7',
    ext_modules = cythonize(extensions, compiler_directives={'language_level': 3}),
    package_dir={'sonicparanoid': 'sonicparanoid/'},
    include_package_data=True,
    package_data={'sonicparanoid': ['example/test_output/*', 'example/test_input/*', 'mmseqs2_src/*', 'quick_multi_paranoid/*']
                },
    entry_points={  # Optional
        'console_scripts': [
            'sonicparanoid = sonicparanoid.sonicparanoid:main',
        ],
    },
)
目前,如果我执行
python3 sonicparanoid.py
,一切正常,但当我使用使用setuptools生成的程序时,我会出现以下错误:

Traceback (most recent call last):
  File "/usr/local/bin/sonicparanoid", line 11, in <module>
    load_entry_point('sonicparanoid==0.0.2', 'console_scripts',     'sonicparanoid')()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 572, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2755, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2408, in load
    return self.resolve()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py",     line 2414, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python3.6/site-packages/sonicparanoid-0.0.2-py3.6-    macosx-10.13-x86_64.egg/sonicparanoid/sonicparanoid.py", line 5, in <module>
    import seq_tools as seqtools
ModuleNotFoundError: No module named 'seq_tools'
回溯(最近一次呼叫最后一次):
文件“/usr/local/bin/sonicparanoid”,第11行,在
加载入口点('SonicPanoid==0.0.2','console\u脚本','SonicPanoid')()
文件“/usr/local/lib/python3.6/site packages/pkg_resources/__init__.py”,第572行,加载入口点
返回获取分布(dist)。加载入口点(组、名称)
文件“/usr/local/lib/python3.6/site packages/pkg_resources/__init__.py”,第2755行,在加载入口点
返回ep.load()
文件“/usr/local/lib/python3.6/site packages/pkg_resources/_init__.py”,第2408行,已加载
返回self.resolve()
文件“/usr/local/lib/python3.6/site packages/pkg_resources/__init__.py”,第2414行,在resolve中
module=\uuuu导入(self.module\u name,fromlist=[''\uuuu name\uuuuuuu'],级别=0)
文件“/usr/local/lib/python3.6/site packages/sonicparanoid-0.0.2-py3.6-macosx-10.13-x86_64.egg/sonicparanoid/sonicparanoid.py”,第5行,in
将seq_工具作为seq工具导入

ModuleNotFoundError:没有名为“seq_tools”的模块
我已经尝试使用本文中提出的解决方案, 但是,如果我将导入更改为,例如,从SonicPanoid导入seq_tools更改为seqtools,然后运行
python3 SonicPanoid.py
我会得到一个导入错误
ImportError:无法导入名称“seq_tools”


任何帮助都将不胜感激,这是我第一次尝试打包,而且非常令人沮丧。

Python使用
sys.path
查找模块/包,并将脚本目录前置到
sys.path
的开头。考虑到这一点,让我们来了解导入的细节

运行
python-sonicpanoid/sonicpanoid.py
python会将目录
sonicpanoid/
添加到
sys.path
。现在,当目录位于
sys.path
中时,脚本可以直接导入
seq_tools
,因为模块
seq_tools.py
位于
sys.path
中的目录中

安装软件包并运行生成的入口点
sonicpanoid
时,目录
sonicpanoid/
不在
sys.path
(但其父目录是)中,Python无法导入
seq\u tools
。您必须将其作为
sonicPanoid.seq_tools
导入。但这意味着,当您以脚本形式运行
sonicpanoid.py
时,无法从
sonicpanoid.py
导入它

一句话:不要以脚本的形式运行
sonicpanoid.py
,因为
sys.path
与运行入口点导入
sonicpanoid
包太不一样了

此外,脚本的名称不能与Python包的名称相同。当您有一个包
sonicparanoid
和一个脚本
sonicparanoid.py
并且脚本尝试
导入sonicparanoid
-Python尝试从脚本导入(因为它是
sys.path
中的第一个),而不是从包导入,并且失败


您可以将脚本命名为
sonicpanoid
(没有
.py
扩展,Python不会尝试从中导入)或
sonic\u paranoid.py
,但不能命名为
sonicpanoid.py

Hello@phd,谢谢。我已经按照您的建议重命名了主脚本sonic_paranoid.py,现在错误不同了。它现在似乎与入口点有关,我将其改为‘sonicparanoid=sonicparanoid.sonic_paranoid:main’。Bt现在似乎根本找不到该脚本,并以错误“ModuleNotFoundError:没有名为“sonicparanoid.sonic_paranoid”的模块退出。在这一点上,我真的很困惑。请注意,我没有更改导入,仍然如问题中所述。ModuleNotFoundError:没有名为“sonicparanoid.sonic_paranoid”的模块。我已经将入口点更改为“sonicparanoid=sonicparanoid.sonic paranoid:main”。似乎您重命名了
sonicparanoid.py
,但没有重新安装程序包,因此安装时仍然是
sonicparanoid/sonicparanoid.py
。是吗?博士你好,非常感谢。看来错误已经过去了。我可以将所有导入替换为“从包导入模块名称为新名称”。非常棘手的,对我来说也是无法解释的部分是,python3解释器不允许我以那种导入风格的旧方式运行脚本,但是在构建和安装bdist之后,脚本也可以以“旧方式”运行。现在仍然有一些问题,因为我也使用Cython,但它是伟大的,我可以解决与您的帮助下,这个开始的问题。非常感谢。现在,当它修复后,我更新了我的答案,以提供有关导入的更多详细信息。您可以将
sonic_paranoid.py
重命名回
sonicparanoid.py
,但不能将其作为脚本运行。
Traceback (most recent call last):
  File "/usr/local/bin/sonicparanoid", line 11, in <module>
    load_entry_point('sonicparanoid==0.0.2', 'console_scripts',     'sonicparanoid')()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 572, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2755, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2408, in load
    return self.resolve()
  File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py",     line 2414, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python3.6/site-packages/sonicparanoid-0.0.2-py3.6-    macosx-10.13-x86_64.egg/sonicparanoid/sonicparanoid.py", line 5, in <module>
    import seq_tools as seqtools
ModuleNotFoundError: No module named 'seq_tools'