【问题标题】:Relative import modules from sub packages in main来自 main 中子包的相对导入模块
【发布时间】:2021-03-28 16:44:12
【问题描述】:

如何从main的子包中导入模块,以便在本地项目目录和pip安装程序时都导入正确的文件?

让我们看一下项目目录的典型结构。

spam
└── spam
    ├── egg
    │   ├── egg.py
    │   └── __init__.py
    ├── bacon
    │   ├── bacon.py
    │   └── __init__.py
    ├── __init__.py
    └── main.py

主要我想导入eggbacon。 现在我用

from egg import egg
from bacon import bacon

当我使用python main.py 在项目目录中运行程序时,这可以正常工作。 但是,在使用 pip 安装程序并在任何非项目目录中运行它后,我会得到以下信息:No module named 'egg'。 为了使它工作,我需要:

from spam.egg import egg
from spam.bacon import bacon

但是,这种方法有一个重要缺点。 现在,如果我在本地运行程序,模块是从 pip 安装中导入的,而不是从本地项目目录中导入的。

我尝试过类似的相对导入:

from .egg import egg

from ..egg import egg

但他们返回ImportError: attempted relative import with no known parent package

我检查了 GitHub 上的几个项目,看看人们是如何做到这一点的,结果发现他们都使用from spam.egg import egg 方法。 我怀疑这是正确的方法。 如果项目中的 shell 运行了一些测试,它们可能会错误地通过或失败,因为正在使用 pip 安装的模块,而不是本地模块。

【问题讨论】:

    标签: python import pip


    【解决方案1】:

    试试这个:

    $ head *.py */*.py
    ==> main.py <==
    import egg,bacon
    egg.egg_func()
    bacon.bacon_func()
    
    
    ==> bacon/bacon.py <==
    def bacon_func():
     print("im a bacon")
    
    
    ==> bacon/__init__.py <==
    from .bacon import bacon_func
    
    
    ==> egg/egg.py <==
    def egg_func():
     print("im an egg")
    
    
    ==> egg/__init__.py <==
    from .egg import egg_func
    

    $ tree
    .
    ├── bacon
    │   ├── bacon.py
    │   ├── __init__.py
    │   └── __pycache__
    │       ├── bacon.cpython-38.pyc
    │       └── __init__.cpython-38.pyc
    ├── egg
    │   ├── egg.py
    │   ├── __init__.py
    │   └── __pycache__
    │       ├── egg.cpython-38.pyc
    │       └── __init__.cpython-38.pyc
    └── main.py
    
    4 directories, 9 files
    

    输出是:

    $ python3 main.py 
    im an egg
    im a bacon
    

    【讨论】:

    • 你没有抓住重点。您已将导入模块替换为导入包。而重点是如何相对指向包。
    • @AlBundy,你的意思是,你想在垃圾邮件之外使用import spam.egg.egg_func
    • 不,我的意思是我不想用包导入替换模块导入。换句话说,我希望 __init__.py 文件为空。尽管如此,您的方法仍然存在与我相同的问题。
    • 我无法清楚地理解您的问题。你想拥有eggbaconspam 作为三个不同的模块?
    • 是的,eggegg子包的模块,baconbacon子包的模块。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    相关资源
    最近更新 更多