【问题标题】:Need help understanding this issue regarding relative vs absolute imports in Python需要帮助理解这个关于 Python 中相对导入和绝对导入的问题
【发布时间】:2018-07-25 03:33:44
【问题描述】:

当我想在特定文件夹中安装某个 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

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

【问题讨论】:

    标签: python import python-import


    【解决方案1】:

    在导入中,您不指定文件夹名称作为包的前缀。如果包已安装或在 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
    

    【讨论】:

    • 如果包在不同的文件夹中,而不是在 python 路径中怎么办?
    • 如果它在非python位置,那么你将不得不附加路径。 import sys sys.path.append('/app/home/others') from myscript import x,y,z
    猜你喜欢
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2019-05-14
    • 2010-12-04
    • 2016-10-09
    相关资源
    最近更新 更多