简体   繁体   English

从子 package 导入模块不起作用

[英]Import a module from a sub package not working

My file structure is我的文件结构是

project/
    __init__.py
    features/
        __init__.py
        CompareText.py
    tests/
        test.py

in test.py I am trying to import CompareText在 test.py 我试图导入 CompareText

from project.features import CompareText

I get an error of:我收到以下错误:

 ModuleNotFoundError: No module named 'features'`

I checked the documentation and I think my import statement is correct.我检查了文档,我认为我的导入语句是正确的。 How can I fix it?我该如何解决?

Your import statement is supposed to look like this: (But make sure your working directory is the same directory as your project folder is located during execution)您的导入语句应该如下所示:(但请确保您的工作目录与执行期间项目文件夹所在的目录相同)

    from project.features import CompareText

This is supposed to work if your current path while executing the script has the project folder如果您在执行脚本时的当前路径具有项目文件夹,这应该可以工作

If you execute it while inside project folder you can use:如果您在项目文件夹中执行它,您可以使用:

    from .features import CompareText

Hope this helps!希望这可以帮助!

Add an __init__ file in test .test中添加一个__init__文件。 Your project directory should look like this:您的项目目录应如下所示:

project/
    __init__.py
    features/
        __init__.py
        CompareText.py
    tests/
        __init__.py
        test.py

Then in project/tests/test.py the following import statement will work:然后在project/tests/test.py中,下面的 import 语句将起作用:

from ..features import CompareText

Oh, and this will still raise an error if you try to run it directly.哦,如果您尝试直接运行它,这仍然会引发错误。 In the question you said you tried to import it like this:在您说您尝试像这样导入它的问题中:

from project.features import CompareText

This will only work if the parent directory of project is in Python's module search path.这仅在project的父目录位于 Python 的模块搜索路径中时才有效。 So, if you want to run the tests directly then modify the module search path as needed (See: sys.path ).因此,如果您想直接运行测试,请根据需要修改模块搜索路径(参见: sys.path )。

I assume you are running test.py as a script.我假设您正在将test.py作为脚本运行。 test.py needs to find the project package and two ways to do that are to make your project installable or to hack sys.path . test.py需要找到project package 并且有两种方法可以使您的项目可安装或破解sys.path

Installable可安装

First, change your directory structure a bit so that project is a subdirectory of some anonymous directory you happen to be using for development.首先,稍微改变一下您的目录结构,使项目成为您碰巧用于开发的某个匿名目录的子目录。 If you are checking this stuff into source control, it needs to be written so that it can be checked out anywhere.如果您要将这些东西签入源代码控制,则需要编写它以便可以在任何地方签出。 Move tests down one directory.tests下移一个目录。

mydevdir/
    setup.py
    project/
        __init__.py
        features/
            __init__.py
            CompareText.py
    tests/
        test.py

How write a setup.py .如何编写setup.py This can get quite complicated.这可能会变得相当复杂。 You can read Building and Distributing Packages with Setuptools and lookup other resources on the net, but a minimalist setup.py is您可以阅读Building and Distributing Packages with Setuptools并在网上查找其他资源,但极简的 setup.py 是

#!/usr/bin/env python

from setuptools import setup, find_packages

setup(name='project',
      version='0.1',
      description='This is project: project',
      packages=find_packages(),
     )

Now, while in mydevdir do python setup.py develop .现在,在mydevdir中执行python setup.py develop Or you can actually produce an install package and put it in a virtual env for test.或者您可以实际生成安装 package 并将其放入虚拟环境中进行测试。

Hack sys.path破解系统路径

It may be easier to hack paths in test.py .test.py中破解路径可能更容易。 Note that this will need to be undone if you make project installable later.请注意,如果您稍后使project可安装,则需要撤消此操作。 Just add to the top of test.py只需添加到test.py的顶部

import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).absolute().parents[2]))

This puts the parent directory in the python path and now project will be found on import.这会将父目录放在 python 路径中,现在将在导入时找到project It runs the risk that a.py file in the same directory as project can mask an installed module.它存在与project位于同一目录中的 .py 文件可能会掩盖已安装模块的风险。 If you have a local csv.py and you import csv , you'd get the local.如果你有一个本地csv.py并且你import csv ,你会得到本地的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM