首页 > 解决方案 > 需要帮助理解这个关于 Python 中相对导入和绝对导入的问题

问题描述

当我想在特定文件夹中安装某个 Python 包(使用 pip install -t),然后从该包中导入一个模块时,我遇到了一个错误。

我在包的 Github 上发布了这个问题,结果发现我无法在某个文件夹中安装包;不支持以这种方式安装软件包。

即使没有 google collab,当我尝试使用 pip install -t sklearnFolder 在某个特定文件夹中安装 sklearn 时,我也可以重现导入错误,然后将其导入为 sklearnFolder.sklearn.manifold。

这不是安装/使用 scikit-lean 的受支持方式。它不起作用的一个原因是 scikit-learn 中的一些模块使用绝对导入(例如 from sklearn import something),这样设置会失败。

您应该使用 pip install 安装它,或者如果您想将它放在某个特定文件夹中,请将 repo 克隆到该文件夹​​,然后运行 ​​pip install -e ,在这两种情况下它将作为 sklearn 导入。

来自https://github.com/scikit-learn/scikit-learn/issues/11656

我不太明白这个解释。

我想像

from folderName.package import module

是相同的

from package import module

因为它们都是绝对进口。如,它们都完全指定了导入模块的路径。所以我的理解有些不对劲,但我不知道它是什么。

标签: pythonimportpython-import

解决方案


在导入中,您不指定文件夹名称作为包的前缀。如果包已安装或在 python 路径中,则只需使用包名即可导入。

    # Assume the below structure is under a directory (folder) called /app/home/packages.

    reservation/                  This is your top-level pacakge 
        __init__.py               Initialize the package
        hotels/                   Subpackage for hotel reservations
            __init__.py
            slots.py
            bid.py
            demand.py
            ...
            restaurents/                  Another Subpackage under hotels 
                __init__.py
                cuisine.py
                hours.py
                tableslots.py
                ...
        rewards/                      Subpackage for rewards
            __init__.py
            points.py
            discounts.py
            membersonly.py
            ...

由于包位于 /app/home/packages 下,因此以下导入无效,因为您为文件夹名称添加前缀。

    from packages.reservation import hotels 

正确的导入方法是从具有包初始化 __init__.py 的实际包中导入。如果您在示例中看到,预订文件夹有 __init__.py。

    from reservation import hotels 

如果你想导入hotels下的子模块,那么你会在包前面加上前缀:

   from reservation.hotels import restaurents

或者,您可以直接导入子模块,但使用时必须在包前面加上前缀:

   import reservation.hotels.restaurents

推荐阅读