如何从另一个目录导入python包? [英] How to Import python package from another directory?

查看:88
本文介绍了如何从另一个目录导入python包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构如下的项目:

I have a project that is structured as follows:

project
├── api
│   ├── __init__.py
│   └── api.py
├── instance
│   ├── __init__.py
│   └── config.py
├── package
│   ├── __init__.py
│   └── app.py
├── requirements.txt
└── tests
    └── __init__.py

我正在尝试从 package/app.py 调用 config.py 文件,如下所示:

I am trying to call the config.py file from the package/app.py as shown below:

# package/app.py
from instance import config

# I've also tried
import instance.config
import ..instance.config
from ..instance import config

但我总是收到以下错误:

But I always get the following error:

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'

修改sys.path 不是我想做的事情.我知道这个问题得到了很好的回答,但给出的答案对我不起作用.

Modifying the sys.path is not something I want to do. I know that this question is very much answered but the answers that were given, did not work for me.

当将 app.py 移动到根文件夹时,它工作得很好.但我需要将它放在 package 文件夹下.

When moving the app.py to the root folder it works just fine. But I need to have it under the package folder.

推荐答案

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

You can add the parent directory to PYTHONPATH, in order to achieve that, you can use OS depending path in the "module search path" which is listed in sys.path. So you can easily add the parent directory like following:

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

from instance import config

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

Note that the previous code uses a relative path, so you must launch the file inside the same location or it will likely not work. To launch from anywhere, you can use the pathlib module.

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

from instance import config

然而,之前的方法更像是一种黑客行为,为了把事情做好,你首先需要根据这篇非常详细的博客文章重塑你的项目结构python 打包,使用 src 文件夹采用推荐的方式.

However, the previous approach is more a hack than anything, in order to do things right, you'll first need to reshape your project structure according to this very detailed blog post python packaging, going for the recommended way with a src folder.

  • 您的目录布局必须如下所示:
project
├── CHANGELOG.rst
├── README.rst
├── requirements.txt
├── setup.py
├── src
│   ├── api
│   │   ├── api.py
│   │   └── __init__.py
│   ├── instance
│   │   ├── config.py
│   │   └── __init__.py
│   └── package
│       ├── app.py
│       └── __init__.py
└── tests
    └── __init__.py

请注意,您实际上并不需要 requirements.txt,因为您可以在 setup.py 中声明依赖项.示例 setup.py(改编自 这里):

Note that you don't really need the requirements.txt because you can declare the dependencies inside your setup.py. A sample setup.py (adapted from here):

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function

import io
import re
from glob import glob
from os.path import basename
from os.path import dirname
from os.path import join
from os.path import splitext

from setuptools import find_packages
from setuptools import setup


def read(*names, **kwargs):
    with io.open(
        join(dirname(__file__), *names),
        encoding=kwargs.get('encoding', 'utf8')
    ) as fh:
        return fh.read()


setup(
    name='nameless',
    version='1.644.11',
    license='BSD-2-Clause',
    description='An example package. Generated with cookiecutter-pylibrary.',
    author='mpr',
    author_email='contact@ionelmc.ro',
    packages=find_packages('src'),
    package_dir={'': 'src'},
    include_package_data=True,
    zip_safe=False,
    classifiers=[
        # complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Operating System :: Unix',
        'Operating System :: POSIX',
        'Operating System :: Microsoft :: Windows',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: Implementation :: CPython',
        'Programming Language :: Python :: Implementation :: PyPy',
        # uncomment if you test on these interpreters:
        # 'Programming Language :: Python :: Implementation :: IronPython',
        # 'Programming Language :: Python :: Implementation :: Jython',
        # 'Programming Language :: Python :: Implementation :: Stackless',
        'Topic :: Utilities',
    ],
    keywords=[
        # eg: 'keyword1', 'keyword2', 'keyword3',
    ],
    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
    install_requires=[
        # eg: 'aspectlib==1.1.1', 'six>=1.7',
    ],
    extras_require={
        # eg:
        #   'rst': ['docutils>=0.11'],
        #   ':python_version=="2.6"': ['argparse'],
    },
    setup_requires=[
        # 'pytest-runner',
    ],
    entry_points={
        'console_scripts': [
            'api = api.api:main',
        ]
    },
)

我的api.py的内容:

from instance import config

def main():
    print("imported")
    config.config()

我的config.py的内容:

def config():
    print("config imported successfully")

您可以在这里找到所有以前的内容

  • 可选但推荐:创建一个虚拟环境,我使用 venv (Python 3.3 <=),在项目的根目录中:
  • Optional but recommended: create a virtual environment, I use venv (Python 3.3 <=) for that, inside the root of the project:
python -m venv .

并激活:

source bin/activate

  • 现在我可以安装包了:
  • 在项目的根目录中使用 pip install -e .(带点)命令

    Using pip install -e . (with the dot) command inside the root of the project

    • 您的导入 from instance import config 现在可以使用了,以确认您可以使用以下命令运行 api.py:
    • Your import from instance import config works now, to confirm you can run api.py with:
    python src/api/api.py
    

    这篇关于如何从另一个目录导入python包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆