繁体   English   中英

无法从不同目录导入 python 模块

[英]Failed to import python module from different directory

我在 python3 中有这个代码结构:

- datalake
  __init__.py
  utils
     __init__.py
     utils.py
  lambdas
     __init__.py
     my-lambdas.py
- tests
    __init__.py
    demo.py

所有init__.py文件都是空的。

我的问题是如何从tests/demo.py datalake模块? 我尝试from datalake.utils import utils in demo.py但是当我从命令行运行python tests/demo.py时,我收到此错误ModuleNotFoundError: No module named 'datalake'

如果我使用这段代码:

from ..datalake.utils import utils

我将收到错误ValueError: attempted relative import beyond top-level package

我还尝试从utils文件导入模块my-lambda.py程序,但也失败了。 my-lambda.py中的代码from datalake.utils import utils ,但在从命令行运行python datalake/lambda/my-lambda.py时出现ModuleNotFoundError: No module named 'datalake'错误。

如何导入模块?

当您运行像python tests/demo.py这样的命令时,您python tests/demo.py的文件夹不会被添加到 PYTHONPATH,脚本文件夹会。 因此,像import datalake这样的顶级import datalake将失败。 要解决此问题,您可以将测试作为模块运行:

蟒蛇2:

python -m tests/demo

蟒蛇3:

python -m tests.demo

并且datalake中的任何数据datalake导入demo.py将起作用。

听起来您真正想做的是拥有一个包含与主应用程序分开的测试的文件夹并运行它们。 为此,我推荐py.test ,对于您的情况,您可以阅读应用程序代码之外的测试以了解如何执行此操作。 TL;DR 使用python -m py.test从你的顶级项目文件夹运行你的测试,它会工作。

首先, my-lambdas.py不能用import语句导入,因为连字符在 Python 标识符中无效。 尝试遵循PEP-8 的命名约定,例如mylambdas.py

否则,包结构看起来不错,只要您处于datalake/之上的级别,它就应该是可导入的,例如,如果您位于以下目录myproject/中:

myproject
├── datalake
│   ├── __init__.py
│   ├── utils
│   │   ├── __init__.py
│   │   └── utils.py
│   └── lambdas
│       ├── __init__.py
│       └── mylambdas.py
└── tests
    ├── __init__.py
    └── demo.py

那么这应该有效:

~/myproject$ python -c 'from datalake import utils'

否则,将环境变量 PYTHONPATH 设置为datalake/上方的路径或修改sys.path都是更改 Python 可以从何处导入的方法。 有关更多信息,请参阅有关模块的官方教程

还有一些一般性建议:我发现在需要扩展之前坚持使用简单的模块而不是包(目录)很有用。 然后,您可以将foo.py更改为带有__init__.py文件的foo/目录, import foo将像以前一样工作,尽管您可能需要向__init__.py添加一些导入以保持 API 兼容性。 这会给你一个更简单的结构:

myproject
├── datalake
│   ├── __init__.py
│   ├── utils.py
│   └── lambdas.py
└── tests
    ├── __init__.py
    └── demo.py

您可以将模块目录添加到您的sys.path

import sys
sys.path.append("your/own/modules/folder")  # like sys.path.append("../tests")

但这是一种一次性的方法,此时只是有效,添加的路径不是永久的,代码执行完成后会被消除。

直接导入文件而不是使用 from 的方法之一,例如import util

你可以尝试运行:

python -m datalake.lambda.my-lambda

关注: https : //docs.python.org/3.7/using/cmdline.html#cmdoption-m

暂无
暂无

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

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