我不确定您要从哪个main 导入。我认为 python 也对路径感到困惑。 test_main.py 如何选择运行哪个 main?通常,当您有一个包(带有__init__.py 的目录)时,您从包而不是单个模块中导入。
# test_main.py
# If img_select is in the path and has __init__.py
from img_select.main import somefunction
如果img_select 没有__init__.py 并且路径中有img_select,则可以从main 导入。
# test_main.py
# If img_select is in the path without __init__.py
from main import somefunction
在您的情况下,我不知道您如何尝试指示要从哪个 main.py 导入。您如何导入和调用正确的config.py?
您也许可以使用os.chdir 更改当前目录。 我认为你的主要问题是img_select 是一个带有__init__.py 的包。当 main 位于包中时,Python 不喜欢使用 from main import ...。 Python 期望使用 from img_select.main import ...。
工作目录
如果您在目录modules/img_select/test/ 中并调用python test_main.py,则此目录称为您的工作目录。您的工作目录位于您调用python 的任何位置。如果您在顶级目录(requirements.txt 所在的位置)并调用python modules/img_select/test/test_main.py,那么顶级目录就是工作目录。 Python 使用这个工作目录作为路径。
如果kernel 有一个__init__.py,那么python 将从顶级目录中找到kernel。如果kernel 不是一个包,那么您需要将kernel 目录添加到路径中,以便python 看到kernel/main.py。一种方法是按照您的建议修改 sys.path 或 PYTHONPATH。但是,如果您的工作目录是 modules/img_select/test/,那么您必须上几个目录才能找到正确的路径。
# test_main.py
import sys
TEST_DIR = os.path.dirname(__file__) # modules/img_select/test/
IMG_DIR = os.path.dirname(TEST_DIR)
MOD_DIR = os.path.dirname(IMG_DIR)
KERNEL_DIR = os.path.join(os.path.dirname(MOD_DIR), 'kernel')
sys.path.append(KERNEL_DIR)
from main import somefunction
如果您的顶级目录(requirements.txt 所在的位置)是您的工作目录,那么您仍然需要将 kernel 添加到路径中。
# modules/img_select/test/test_main.py
import sys
sys.path.append('kernel')
正如您所见,这可能会根据您的工作目录而改变,您必须手动修改每个正在运行的文件。你可以像你正在做的那样用 abspath 来解决这个问题。但是,每个文件都需要修改路径。我不建议手动更改路径。
库
Python 路径可能很痛苦。我建议建立一个图书馆。
您只需创建一个setup.py 文件即可将kernel 或其他软件包安装为库。 setup.py 文件应与requirements.txt 处于同一级别
# setup.py
"""
setup.py - Setup file to distribute the library
See Also:
* https://github.com/pypa/sampleproject
* https://packaging.python.org/en/latest/distributing.html
* https://pythonhosted.org/an_example_pypi_project/setuptools.html
"""
from setuptools import setup, Extension, find_packages
setup(name='kernel',
version='0.0.1',
# Specify packages (directories with __init__.py) to install.
# You could use find_packages(exclude=['modules']) as well
packages=['kernel'], # kernel needs to have __init__.py
include_package_data=True,
)
kernel 目录需要__init__.py。如果您仍在使用该库,请将其安装为可编辑的。在具有setup.py 文件的顶级目录中调用pip install -e .。
安装库后,python 会将kernel 目录复制或链接到其site-packages 路径中。现在您的test_main.py 文件只需要正确导入内核
# test_main.py
from kernel.main import somefunction
somefunction()
自定义 init.py
>
由于内核现在有一个__init__.py,您可以通过导入kernel来控制可用的功能
# __init__.py
# The "." indicates a relative import
from .main import somefunction
from .config import ...
try:
from .src.mymodule import myfunc
except (ImportError, Exception):
def myfunc(*args, **kwargs):
raise EnvironmentError('Function not available. Missing dependency "X".')
更改 __init__.py 后,您可以从内核而不是 kernel.main 导入
# test_main.py
from kernel import somefunction
somefunction()