python import 上级目录的导入
有时候我们可能需要import另一个路径下的python文件,例如下面这个目录结构,我们想要在_train.py里import在networks目录下的_lstm.py和上级目录下的_config.py。 _config.py networks _lstm.py _cnn.py pipelines _train.py 只需两步操作 (1)在networks文件夹下创建空的__init__.py文件 _config.py networks _lstm.py _cnn.py pipelines _train.py (2)使用sys库添加路径 # _train.py i 在Python编程中,有时我们需要在不同的目录结构之间导入模块,特别是在大型项目中,合理的文件组织和模块间的相互引用是至关重要的。本篇文章将详细介绍如何在Python中实现从上级目录导入模块,以及处理不同目录结构下的导入问题。 我们要了解Python的模块查找机制。当Python尝试导入一个模块时,它会按照sys.path列表中的路径顺序查找。sys.path是一个包含字符串的列表,表示Python搜索模块的路径。默认情况下,sys.path包括当前工作目录、标准库目录以及环境变量PYTHONPATH指定的其他路径。 在给定的场景中,我们有以下目录结构: ``` _project/ |-- _config.py |-- networks/ | |-- __init__.py | |-- lstm.py | |-- cnn.py |-- pipelines/ | |-- train.py ``` 如果在`pipelines/train.py`中需要导入`networks/lstm.py`和`_config.py`,可以按照以下步骤操作: 1. **创建`__init__.py`文件**:在`networks`目录下创建一个空的`__init__.py`文件。这个文件告诉Python,`networks`是一个包,这样我们就可以使用相对导入来引用其中的子模块。如果没有`__init__.py`,Python将不会识别该目录为一个包。 2. **修改`sys.path`**:在`train.py`中,我们需要通过`sys.path.append()`来添加上级目录到sys.path中,以便能够找到`_config.py`。代码如下: ```python import sys sys.path.append("..") # 添加上级目录到sys.path from networks._lstm import * # 导入networks包下的_lstm模块 from _config import * # 导入上级目录的_config模块 ``` 然而,有些同学反馈在Python 3.6.7及以上版本中,上述方法可能不再有效。这是因为Python引入了更严格的导入规则。为了解决这个问题,我们可以使用更通用的解决方案,即遍历上级目录及其子目录,将它们添加到sys.path。代码如下: ```python import sys, os # 添加上级目录及其所有子目录到sys.path sys.path.extend([os.path.join(root, name) for root, dirs, _ in os.walk("..") for name in dirs]) ``` 这种方法虽然不那么优雅,但它能确保所有子目录都被考虑,即使目录结构变得更加复杂。 此外,为了更好地管理和理解代码,建议避免使用`from module import *`这种导入方式,因为它会导致代码难以阅读和维护。最好明确地列出需要导入的函数或类,如`from networks._lstm import LSTMModel, LSTMConfig`。 在Python中导入上级目录或其他非标准路径的模块,关键在于正确调整sys.path和理解Python的模块查找机制。通过创建`__init__.py`文件和适当修改sys.path,我们可以轻松地在不同目录之间进行导入。同时,遵循良好的编程实践,如使用明确的导入语句,将有助于提高代码的可读性和可维护性。