Python 使用 setup.py 在安装的包上导入错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15368054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:55:41  来源:igfitidea点击:

Import error on installed package using setup.py

pythonimportpython-2.7setuptools

提问by Alex

I have a problem with using setup.pyto setup a python package. First, I have the following directory setup:

我在使用setup.py设置 python 包时遇到问题。首先,我有以下目录设置:

maindir
   |- setup.py
   |-mymodule
         |- __init__.py
         |- mainmodule.py
         |-subdir
             |- __init__.py
             |- submodule.py

i.e. the project directory contains the setup.pyand a directory mymodule, which in itself contains two python modules in two directories. The file submodule.pycontains just

即项目目录包含setup.py和一个目录mymodule,它本身在两个目录中包含两个python模块。该文件submodule.py仅包含

teststring = "hello world"

mainmodule.pycontains:

mainmodule.py包含:

from .subdir import submodule
mainstring = "42"

and setup.pycontains:

setup.py包含:

import os
from setuptools import setup
setup(
    name = "mytestmodule",
    version = "0.0.1",
    description = ("A simple module."),
    packages=['mymodule'],
)

When I do from mymodule import mainmodulewith ipythonfrom within sourceTestthe behaviour works as expected and I can reference e.g. mainmodule.submodule.teststringwhich gives me the string hello world.

当我from mymodule import mainmodule使用ipythonfrom 时sourceTest,行为按预期工作,我可以引用例如mainmodule.submodule.teststring它给我的字符串hello world

On the other side, when I install this 'package' using python setup.py installand try to do the same (from within some other directory), I get an import error:

另一方面,当我使用安装此“包”python setup.py install并尝试执行相同操作(从其他目录中)时,出现导入错误:

In [1]: from mymodule import mainmodule
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
/home/alexander/<ipython-input-1-cf4c9bafa487> in <module>()
----> 1 from mymodule import mainmodule

/home/alexander/build/bdist.linux-i686/egg/mymodule/mainmodule.py in <module>()

ImportError: No module named subdir

I do not see what I have done wrong, as I followed a Getting started tutorialand rules for importing intra-packages. I suppose my mistake is a really tiny one, but I cannot spot it and help is appreciated.

我没有看到我做错了什么,因为我遵循了入门教程导入内部包的规则。我想我的错误是一个很小的错误,但我无法发现它并感谢帮助。

采纳答案by Pavel Anossov

You have to list all packages in setup, including subpackages:

您必须列出 中的所有包setup,包括子包:

setup(
    name = "mytestmodule",
    version = "0.0.1",
    description = ("A simple module."),
    packages=['mymodule', 'mymodule.subdir'],
)

Or you can use setuptools's magic function find_packages:

或者你可以使用setuptools的魔法功能find_packages

from setuptools import setup, find_packages
setup(
    name = "mytestmodule",
    version = "0.0.1",
    description = ("A simple module."),
    packages=find_packages(),
)

This is mentioned here:

这是在这里提到的:

If you have sub-packages, they must be explicitly listed in packages, but any entries in package_dir automatically extend to sub-packages. (In other words, the Distutils does not scan your source tree, trying to figure out which directories correspond to Python packagesby looking for __init__.pyfiles.)

如果您有子包,它们必须在包中明确列出,但 package_dir 中的任何条目都会自动扩展到子包。(换句话说,Distutils 不会扫描你的源代码树,试图通过查找__init__.py文件来找出哪些目录对应于 Python 包。)

回答by Shubham Chaudhary

You need to specify your each modules explicitly. Instead of maintaining the complexity of adding module to setup.py everytime, you may use the find_packagesmethod from setuptools.

您需要明确指定每个模块。相反,保持添加模块来setup.py每次的复杂性,你可以使用find_packages从方法setuptools

find_packagestakes two optional arguments:

find_packages接受两个可选参数:

  1. wherewhich is default to '.'i.e your curdir.
  2. excludelist of stuff to exclude
  1. where默认为'.'即您的curdir。
  2. exclude要排除的东西列表

I usually have tests in my repo, so I use:

我通常在我的 repo 中有测试,所以我使用:

from setuptools import find_packages

packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]),

回答by ThorSummoner

I had scriptname.py:mainin my setup.py console_scripts, the .pyis redundant.

我在我的 setup.py console_scripts 中有,这是多余的。scriptname.py:main.py