导入当前折叠的同级中的库

2024-04-26 02:18:42 发布

您现在位置:Python中文网/ 问答频道 /正文

文件夹结构

lib/
    abcd/
        __init.py__
        lib.py
app.py

代码

^{pr2}$

有效。但是使用这种文件结构:

bin/
    app.py
lib/
    abcd/
        __init.py__
        lib.py

代码

from ..lib.abcd import lib     

提供导入错误。在

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

我知道可能有一些黑客会在路径中添加lib/,但是有没有一个优雅的python解决方案呢?在

如果没有,是否有真正的内部原因阻止用户以简单的方式进行这种简单的导入?在


Tags: 文件代码frompyimport路径文件夹app
2条回答

表面水平外观

通常情况下,您不能。当导入一个文件时,Python只搜索当前目录、运行入口点脚本的目录以及sys.path,其中包括诸如包安装目录之类的位置(它实际上比这复杂一些,但这涵盖了大多数情况)。在

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

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

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

    import file  

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

我已经广泛地阅读了import documentation,据我所知,你的问题的答案是不,没有办法用纯粹的“Python”的方式来做这件事。在

更深入了解:

深入研究import documentation可以解释这一点:

The import statement combines two operations; it searches for the named module, then it binds the results of that search to a name in the local scope. The search operation of the import statement is defined as a call to the __import__() function, with the appropriate arguments. The return value of __import__() is used to perform the name binding operation of the import statement.

仔细看一下__import__

__import__(name, globals=None, locals=None, fromlist=(), level=0)

Note: This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().

This function is invoked by the import statement. It can be replaced (by importing the builtins module and assigning to builtins.__import__) in order to change semantics of the import statement, but doing so is strongly discouraged as it is usually simpler to use import hooks (see PEP 302) to attain the same goals and does not cause issues with code which assumes the default import implementation is in use. Direct use of __import__() is also discouraged in favor of importlib.import_module().

level specifies whether to use absolute or relative imports. 0 (the default) means only perform absolute imports. Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__() (see PEP 328 for the details).

这使我认为您可以以某种方式指定一个level,使导入自动查找父路径。我猜,当import从你的app.py调用时,level被设置为0,它搜索的层次和深度相同。在

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

这样做的方法


方法1:使用sys模块:您可以使用sys模块轻松完成您要做的事情。要导入lib包,可以使用下面列出的两个代码之一:

import sys
sys.path.append('<PATH_TO_LIB_FOLDER>')

from lib.abcd import lib

或者

^{pr2}$

方法2:使用os模块:另一种方法是使用os模块。下面是一个示例代码,通过调用os.path.join方法,使用os模块导入lib模块:

import os

path = os.path.join("<PATH>/lib/abcd", "lib")
from lib.abcd import lib

方法3:将模块添加到python路径:在大多数情况下,这不是最好的方法,但是如果您不想继续使用sys或{}模块来导入lib,这是理想的方法。您只需在bash终端中键入以下内容:

export PYTHONPATH=<PATH_TO_LIB> python lib.py

然后在python shell中,可以如下导入:

from lib.abcd import lib

方法4:结合sys和os模块(推荐):这是最有效的方法,可以节省大量时间。此代码将ossys模块组合在一起,如下所示:

import sys, os
sys.path.append(os.path.abspath(os.path.join('..', 'lib')))

然后您可以像这样轻松地导入模块:

from lib.abcd import lib

所有代码的工作原理:

上面所有的代码都很简单。除了“Method 3”之外,所有示例都将您的模块临时添加到PYTHONPATH中。另一方面,“Method#3”将模块永久添加到您的PYTHONPATH中。在

相关问题 更多 >