简体   繁体   English

无法从 Python 3.7.1 中的其他目录导入模块

[英]Not able to import module from other directory in Python 3.7.1

I have a package structured as:我有一个 package 结构为:

在此处输入图像描述

Classes in those packages are named exactly like the file names.这些包中的类的命名与文件名完全相同。 Also, init .py has following code此外, init .py 有以下代码

from tableau_util import tableau_util
from sftp_util import sftp_util
from s3_util import s3_util

I have another file eg test.py which is outside this folder 'utils'.我有另一个文件,例如 test.py,它位于此文件夹“utils”之外。 I want to import those classes into test.py so my code is我想将这些类导入 test.py 所以我的代码是

from utils.tableau_util import tableau_util
from utils.sftp_util import sftp_util
from utils.s3_util import s3_util

I am still getting the error:我仍然收到错误:

ModuleNotFoundError: No module named 'tableau_util' ModuleNotFoundError:没有名为“tableau_util”的模块

What can I try to resolve this?我可以尝试什么来解决这个问题?

Without knowing everything I would guess that you are trying to run your test.py as a normal python script.在不知道所有内容的情况下,我猜您正在尝试将test.py作为普通的 python 脚本运行。 Given this folder structure鉴于此文件夹结构

.
├── __init__.py
├── test
│   ├── __init__.py
│   └── test.py
└── utils
    ├── __init__.py
    ├── s3_util.py
    └── tableau_util.py

with these files test.py使用这些文件test.py

from utils.s3_util import s3_util
from utils.tableau_util import tableau_util

s3_util()
tableau_util()

import sys

print(sys.path)

s3_util.py

def s3_util():
    print('Im a s3 util!')

tableau_util.py

def tableau_util():
    print('Im a tableu util!')

if you just tried to run python test/test.py in the main folder it will give you the ModuleNotFoundError .如果您只是尝试在主文件夹中运行python test/test.py ,它将为您提供ModuleNotFoundError That's because it sets the ./test folder as the python path and it won't be able to see the utils folder and therefore be able to import it.那是因为它将./test文件夹设置为 python 路径,它将无法看到utils文件夹,因此无法导入它。 However if you run it as python -m test.test (note the lack of .py you don't need it when you run it as a module) that will tell python to load it as a module and then it will run correctly with this output:但是,如果您将其作为python -m test.test运行(注意缺少.py ,当您将其作为模块运行时不需要它),这将告诉 python 将其作为模块加载,然后它将正确运行这个 output:

Im a s3 util!
Im a tableau util!

If you don't want to put the test.py in another folder you can simply keep it in the parent folder of utils and be able to run it in the traditional python test.py and get the same results.如果您不想将test.py放在另一个文件夹中,您可以简单地将其保存在utils的父文件夹中,并能够在传统的python test.py中运行它并获得相同的结果。 Error while finding spec for 'fibo.py' (<class 'AttributeError'>: 'module' object has no attribute '__path__') has some more reading on the matter. 查找“fibo.py”规范时出错(<class 'AttributeError'>: 'module' object has no attribute '__path__')对此事有更多了解。

For the record all my __init__.py files are empty and don't import anything and this is normally how they are setup unless you want to specify certain functions that need to be imported when the module is imported automatically.作为记录,我的所有__init__.py文件都是空的,并且不导入任何东西,这通常是它们的设置方式,除非您想指定在自动导入模块时需要导入的某些功能。

I used PyCharm's create package option to create folders and files again and it is working now.我使用 PyCharm 的 create package 选项再次创建文件夹和文件,它现在正在工作。 Here are my new (working) folder structure:这是我的新(工作)文件夹结构:
在此处输入图像描述

My main script has following lines of code to import those classes:我的主脚本有以下代码行来导入这些类:

from utils_pkg import tableau_util
from utils_pkg import s3_util
from utils_pkg import sftp_util

First, inside __init__.py (or in any sub-module that tries to import one of its siblings from the same package) you should add a "relative import" dot to the beginning of the module name, so that it reads:首先,在__init__.py中(或在任何试图从同一个包中导入其兄弟姐妹的子模块中),您应该在模块名称的开头添加一个“相对导入”点,以便它读取:

from .tableau_util import tableau_util
#    ^right here

Second, make sure your current working directory is not utils .其次,确保您当前的工作目录不是utils A good place to start, for testing, might be to cd to the parent directory of utils instead.一个好的开始测试的地方可能是cdutils的父目录。

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

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