我有一个项目的 struct 如下:

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

我正在try 从package/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'

修改sys.path不是我想做的事.

EDIT:app.py移动到根文件夹时,效果很好.但我需要把它放在package文件夹下.

推荐答案

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

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

from instance import config

请注意,前面的代码使用相对路径,因此必须在同一位置启动文件,否则可能无法运行.要从任何地方emits ,可以使用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

然而,前面的方法更像是一种黑客行为,为了把事情做好,你首先需要根据这篇非常详细的博文python packaging来reshape 你的项目 struct ,使用src文件夹的推荐方法.

  • 您的目录布局必须如下所示:
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中声明依赖项.

#!/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',
        ]
    },
)

my api.py的内容:

from instance import config

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

my config.py的内容:

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

你可以找到之前的here

  • 可选但推荐:创建一个虚拟环境,我使用venv(Python 3.3<;=)在项目的根目录中:
python -m venv .

并激活:

source bin/activate
  • 现在我可以安装软件包了:

使用pip install -e .(带点)命令inside the root of the project

  • 您的import from instance import config现在可以运行了,以确认您可以运行api.带:
python src/api/api.py

Python-3.x相关问答推荐

Gekko优化超出了方程式的界限(由于某种原因,会产生变量)

只有在Chrome尚未打开的情况下,打开Chrome后,PySimpleGUI窗口才会崩溃

将Trio与基于线程的事件侦听器混合使用

我用Kivy创建的应用程序在安卓系统上运行时出错.(attributeerror:';class';对象没有属性';_javaclass__cls_storage';)

Python webdrivermanager 和 Chrome 115.0 的 URL https://chromedriver.storage.googleapis.com/LATEST_RELEASE_115.0.5790 错误没有此类驱动程序

SQL Server 2022和Python3.10脚本错误

找到在指定列的另一个分组中存在重复的行.

Python 3 - 给定未知数量的类别动态地将字典嵌套到列表中

多进程:两个进程,一起杀死

Python Regex 查找给定字符串是否遵循交替元音、辅音或辅音、元音的连续模式

Jupyter Notebook 拒绝打印一些字符串

以编程方式映射 uniprot ID 时如何解决 400 客户端错误?

通过附加/包含多个列表来创建 nDimensional 列表

理解 Keras 的 ImageDataGenerator 类中的 `width_shift_range` 和 `height_shift_range` 参数

str.format_map(mapping) 和 str.format 有什么区别

如何在多核上运行 Keras?

Python3 - 如何从现有抽象类定义抽象子类?

如何在python中创建代码对象?

如何在 QGraphicsView 中启用平移和zoom

Python 2 与 Python 3 - urllib 格式