导入位于当前文件夹的同级文件中的库

Bas*_*asj 9 python directory import python-import

与文件夹结构

lib/
    abcd/
        __init.py__
        lib.py
app.py
Run Code Online (Sandbox Code Playgroud)

代码

from lib.abcd import lib
Run Code Online (Sandbox Code Playgroud)

作品。但是具有以下文件结构:

bin/
    app.py
lib/
    abcd/
        __init.py__
        lib.py
Run Code Online (Sandbox Code Playgroud)

代码

from ..lib.abcd import lib     
Run Code Online (Sandbox Code Playgroud)

给出导入错误。

import当库位于当前文件夹的同级文件中时,如何正确执行操作?(或同级文件夹的子文件夹)

我知道可能会有一些涉及添加lib/到PATH的黑客,但是是否有一个优雅的Pythonic解决方案?

如果不是,是否有真正的内部原因阻止用户以简单方式执行此简单导入?

Mat*_*one 1

表面水平外观

通常情况下,你不能。导入文件时,Python 仅搜索当前目录、运行入口点脚本的目录以及sys.path包括包安装目录等位置(实际上比这更复杂,但这涵盖了大多数情况) 。

您在导入已安装模块时没有看到此问题的原因是因为它们安装在您的路径上已有的位置,或者该位置由安装实用程序添加到路径中(pip例如)。

您可以在运行时添加到Python路径:

    import sys
    sys.path.insert(0, '../lib')

    import file  
Run Code Online (Sandbox Code Playgroud)

您还可以使用sys.path.append('../lib'),但随后它将在路径中最后搜索,并且可能会被以前的路径条目覆盖。

我已阅读进口文件,据我所知,你的问题的答案是否定的,没有办法以纯粹的“Pythonic”方式做到这一点。

更深入地看:

深入研究导入文档可以解释这一点:

import 语句结合了两个操作;它搜索命名模块,然后将该搜索结果绑定到本地范围内的名称。import 语句的搜索操作定义为使用适当的参数调用__import__()函数。__import__()的返回值用于执行 import 语句的名称绑定操作。

更仔细地观察__import__

__import__(名称、全局=无、局部=无、fromlist=()、级别=0)

注意:与importlib.import_module()不同,这是日常 Python 编程中不需要的高级函数。

该函数由 import 语句调用。它可以被替换(通过导入内置模块并分配给builtins.__import__)以更改导入语句的语义,但强烈建议不要这样做,因为使用导入钩子(参见 PEP 302)通常更容易获得相同的目标,并且不会导致假设正在使用默认导入实现的代码出现问题。也不鼓励直接使用 __import__() ,而是使用importlib.import_module()

level 指定是使用绝对导入还是相对导入。0(默认值)表示仅执行绝对导入。level 的正值表示相对于调用 __import__() 的模块目录要搜索的父目录数(有关详细信息,请参阅 PEP 328)。

这让我认为您可以level以某种方式指定 a ,使导入自动在父路径上查找。我猜测,当从不在它自己的目录中import调用时,设置为并且它搜索相同的级别和更深的级别。 app.pylevel0

当您从子文件夹调用时,import仍设置为,因此无法找到其上方的其他目录。我正在研究一种“Pythonic”方式,在运行脚本时设置此级别,这似乎可以解决此问题。 app.pylevel01