无法用 Python 导入我自己的模块

我很难理解模块导入在 Python 中是如何工作的(我以前也从未用其他语言做过)。

就算我有:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

现在我试图得到这样的东西:

myapp.py
===================
from myapp import SomeObject
# stuff ...


TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

然而,我肯定做错了什么,因为 Python 看不到 myapp是一个模块:

ImportError: No module named myapp
448336 次浏览

函数 import在 PYTHONPATH env 中查找文件。变量和本地目录。因此,您可以将所有文件放在同一个目录中,或者将输入的路径导出到一个终端:

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"

在您的特定情况下,看起来您正试图从 myapp.py 和 TestCase.py 脚本导入 SomeObject。来自 myapp.py

import SomeObject

因为它在同一个文件夹中

from ..myapp import SomeObject

但是 ,这只有在从包中导入 TestCase 时才有效。如果您想直接运行 python TestCase.py,那么必须改变您的路径。这可以在 Python 中完成:

import sys
sys.path.append("..")
from myapp import SomeObject

不过一般不建议这么做。

通常,如果希望其他人使用您的 Python 包,应该使用 蒸馏酒创建安装脚本。这样,任何人都可以使用像 python setup.py install这样的命令轻松地安装您的软件包,并且在他们的机器上任何地方都可以使用它。如果您对这个包是认真的,您甚至可以将它添加到 Python 包索引 PyPI中。

导出路径是一种很好的方法。另一种方法是向站点包位置添加一个. pth。 在我的 mac 上,我的 Python 将站点包保存在/Library/Python 中,如下所示

/Library/Python/2.7/site-packages

我在/Library/Python/2.7/site-package/awesome.pth 创建了一个名为 awesome.pth 的文件,并在该文件中放置了引用我的 Awesome 模块的以下路径

/opt/awesome/custom_python_modules

你可以试试

from myapp.myapp import SomeObject

因为您的项目名称与 myapp.py 相同,这使得它首先搜索项目文档

在第一个 myapp 目录中,您可以添加一个 setup.py 文件,并在 setup.py 中添加两个 python 代码

from setuptools import setup
setup(name='myapp')

在命令行的第一个 myapp 目录中,使用 pip install-e. 来安装包

在我的案例中,这是 Windows 对 Python 的惊喜,尽管 Windows 文件名不区分大小写,但 Python 导入是区分大小写的。因此,如果您有 Stuff.py文件,则需要按原样导入此名称。

Windows 10上的 pip install默认安装在“ Program Files/PythonXX/Lib/site-package”中,这是一个需要管理特权的目录。因此,我通过 作为管理员运行 pip 安装修复了我的问题(即使您使用管理员帐户登录,也必须以管理员身份打开命令提示符)。另外,从 python 调用 pip 更安全。
例如:。
python -m pip install <package-name>
而不是
pip install <package-name>

你需要

__init__.py

在所有包含需要交互的代码的文件夹中。 您还需要在每次导入中指定项目的顶级文件夹名称,即使您试图导入的文件位于相同的级别。

假设我写了一个模块

import os
my_home_dir=os.environ['HOME'] // in windows 'HOMEPATH'
file_abs_path=os.path.join(my_home_dir,"my_module.py")


with open(file_abs_path,"w") as f:
f.write("print('I am loaded successfully')")


import importlib
importlib.util.find_spec('my_module') ==> cannot find

我们必须告诉 python 在哪里寻找模块。我们必须将我们的路径添加到 sys.path

 import sys
sys.path.append(file_abs_path)

现在 importlib.util.find_spec('my_module')返回:

  ModuleSpec(name='my_module', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7fa40143e8e0>, origin='/Users/name/my_module.py')

我们创建了我们的模块,我们通知 python 它的路径,现在我们应该能够导入它

 import my_module


//I am loaded successfully

简短的回答:

python -m ParentPackage.Submodule

通过模块标志执行所需的文件对我来说工作。让我们假设我们得到了一个典型的目录结构如下:

my_project:
| Core
->myScript.py
| Utils
->helpers.py
configs.py

现在,如果你想在一个目录中运行一个文件,这个目录包含从其他模块导入的内容,你所需要做的就是:

python -m Core.myscript

PS: 你必须使用点符号来引用子模块(你想要执行的文件/脚本)。我还使用了 python3.9 + 。因此,我既不需要任何 Init.py 语句,也不需要任何 sys 路径 append 语句。

希望这有帮助! 编码愉快!

这对我很有效:

from .myapp import SomeObject

.表示它将从父模块中搜索任何本地模块。

如果你使用水蟒,你可以做到:

conda develop /Path/To/Your/Modules

它会将您的路径写入 conda.pth 文件到第三方模块的标准目录(在我的例子中是站点包)。

如果您使用的是 IPython 控制台,请确保您的 IDE (例如 spyder)指向正确的工作目录(例如,您的项目文件夹)