如何从另一个目录导入python包?

如何从另一个目录导入python包?,python,python-3.x,python-module,Python,Python 3.x,Python Module,我有一个项目,其结构如下: project ├── api │ ├── __init__.py │ └── api.py ├── instance │ ├── __init__.py │ └── config.py ├── package │ ├── __init__.py │ └── app.py ├── requirements.txt └── tests └── __init__.py 我正试图从包/app.py调用config.py文件,如下所示: #

我有一个项目,其结构如下:

project
├── api
│   ├── __init__.py
│   └── api.py
├── instance
│   ├── __init__.py
│   └── config.py
├── package
│   ├── __init__.py
│   └── app.py
├── requirements.txt
└── tests
    └── __init__.py
我正试图从
包/app.py
调用
config.py
文件,如下所示:

# package/app.py
from instance import config

# I've also tried
import instance.config
import ..instance.config
from ..instance import config
但我总是会遇到以下错误:

Traceback (most recent call last):
  File "/home/csymvoul/projects/project/package/app.py", line 1, in <module>
    from instance import config
ModuleNotFoundError: No module named 'instance'
回溯(最近一次呼叫最后一次):
文件“/home/csymvoul/projects/project/package/app.py”,第1行,在
从实例导入配置
ModuleNotFoundError:没有名为“实例”的模块
我不想修改
sys.path
。 我知道这个问题已经得到了很好的回答,但给出的答案对我来说并不适用


编辑:
app.py
移动到根文件夹时,它工作正常。但是我需要把它放在
文件夹下。

您可以将父目录添加到
PYTHONPATH
,为了实现这一点,您可以在
sys.path
中列出的“模块搜索路径”中使用依赖于操作系统的路径。因此,您可以轻松添加父目录,如下所示:

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

from instance import config
请注意,前面的代码使用相对路径,因此必须在同一位置内启动文件,否则可能无法运行。要从任何地方启动,可以使用
pathlib
模块

from pathlib import Path
import sys
path = str(Path(Path(__file__).parent.absolute()).parent.absolute())
sys.path.insert(0, path)

from instance import config
然而,前面的方法更像是一种黑客行为,为了把事情做好,你首先需要根据这篇非常详细的博文重塑你的项目结构,使用推荐的
src
文件夹

  • 您的目录布局必须如下所示:
请注意,您实际上并不需要
requirements.txt
,因为您可以在
setup.py
中声明依赖项。 示例
setup.py
(改编自):

#/usr/bin/env python
#-*-编码:utf-8-*-
从未来导入绝对导入
来自未来导入打印功能
输入io
进口稀土
从全局导入全局
从os.path导入basename
从os.path导入目录名
从os.path导入联接
从os.path导入拆分文本
从setuptools导入查找包
从设置工具导入设置
def read(*名称,**kwargs):
打开io(
join(dirname(_文件,_),*名称),
encoding=kwargs.get('encoding','utf8')
)作为fh:
返回fh.read()
设置(
name='nameless',
version='1.644.11',
许可证='BSD-2-条款',
description='A示例包。使用cookiecutter PylLibrary生成。',
作者class='mpr',
作者(电邮地址)contact@ionelmc.ro',
packages=find_packages('src'),
包_dir={'':'src'},
include_package_data=True,
zip_safe=False,
分类器=[
#完整分类器列表:http://pypi.python.org/pypi?%3Aaction=list_classifiers
“发展状况:5-生产/稳定”,
'目标受众::开发者',
“许可证::OSI已批准::BSD许可证”,
“操作系统::Unix”,
'操作系统::POSIX',
“操作系统::Microsoft::Windows”,
'编程语言::Python',
'编程语言::Python::2.7',
'编程语言::Python::3',
'编程语言::Python::3.5',
'编程语言::Python::3.6',
'编程语言::Python::3.7',
'编程语言::Python::3.8',
'编程语言::Python::实现::CPython',
'编程语言::Python::实现::PyPy',
#如果在这些解释器上进行测试,请取消注释:
#'编程语言::Python::实现::IronPython',
#'编程语言::Python::实现::Jython',
#'编程语言::Python::实现::Stackless',
'主题::实用程序',
],
关键词=[
#例如:“关键字1”、“关键字2”、“关键字3”,
],
python_需要='>=2.7、!=3.0.*、!=3.1.*、!=3.2.*、!=3.3.*、!=3.4.*',
安装所需的=[
#例如:“aspectlib==1.1.1”,“six>=1.7”,
],
额外需要={
#例如:
#“rst”:['docutils>=0.11'],
#“:python_version==”2.6“:['argparse'],
},
设置\u需要=[
#“pytest runner”,
],
入境点={
“控制台脚本”:[
'api=api.api:main',
]
},
)
my
api.py的内容:

from instance import config

def main():
    print("imported")
    config.config()
def config():
    print("config imported successfully")
my
config.py的内容

from instance import config

def main():
    print("imported")
    config.config()
def config():
    print("config imported successfully")
你可以找到所有以前的


  • 可选但推荐:创建虚拟环境,我使用
    venv
    (Python 3.3在Python 3.3以后的版本中,您不需要在子目录中使用
    \uuuu init\uuu.py
    文件进行导入。拥有这些文件实际上可能会产生误导,因为它会导致在包含init文件的每个文件夹中创建包命名空间,如前所述

    通过删除所有这些
    \uuuu init\uuuuuupy
    文件,您将能够在运行
    app.py
    时导入命名空间
    (包括子目录)中的文件,但这仍然不是我们想要的

    Python解释器仍然不知道如何访问您的
    实例
    命名空间。为此,您可以使用
    PYTHONPATH
    环境变量,包括
    config.py
    的父路径。您可以按照@RMPR的答案中的建议,使用
    sys.path
    ,或者直接设置环境变量t变量,例如:

    PYTHONPATH=/home/csymvoul/projects/project python3 /home/csymvoul/projects/project/package/app.py
    

    然后从实例导入配置导入依赖项,如

    我也检查了这一点,但它似乎不起作用第二个选项工作得很好,但是没有更简单的方法来实现这一点而不干扰路径吗?要使用更简单的方法,您需要调整目录结构,从我的我知道,当我在目录中添加一个
    \uuuu init\uuuuuuuuuu.py
    时,python将它标识为一个模块。为什么现在不是这样呢?我可以调整项目的结构,但我看不出除此之外还有什么不同
    python src/api/api.py
    
    PYTHONPATH=/home/csymvoul/projects/project python3 /home/csymvoul/projects/project/package/app.py