繁体   English   中英

无法在 Python 中导入我自己的模块

[英]Can't import my own modules in 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

在您的特定情况下,您似乎正在尝试从 myapp.py 和 TestCase.py 脚本导入SomeObject 从 myapp.py,做

import SomeObject

因为它在同一个文件夹中。 对于 TestCase.py,执行

from ..myapp import SomeObject

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

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

尽管通常不建议这样做。

一般来说,如果你想让其他人使用你的 Python 包,你应该使用distutils创建一个安装脚本。 这样,任何人都可以使用诸如python setup.py install之类的命令轻松安装您的软件包,并且在他们的机器上随处可用。 如果你对这个包很认真,你甚至可以将它添加到 Python 包索引PyPI中。

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

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

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

/Library/Python/2.7/site-packages

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

/opt/awesome/custom_python_modules

你可以试试

from myapp.myapp import SomeObject

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

你需要有

__init__.py

在所有包含您需要与之交互的代码的文件夹中。 即使您尝试导入的文件处于同一级别,您也需要在每次导入时指定项目的顶级文件夹名称。

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

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

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

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

就我而言,这是 Windows 与 Python 的惊喜,尽管 Windows 文件名不区分大小写,但 Python 导入是。 因此,如果您有Stuff.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

这对我有用:

from .myapp import SomeObject

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

简短的回答:

python -m ParentPackage.Submodule

通过模块标志执行所需的文件对我有用。 假设我们得到了一个典型的目录结构,如下所示:

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

现在,如果你想在一个目录中运行一个文件,该文件具有从其他模块的导入,你需要做的就是如下所示:

python -m Core.myscript

PS:您必须使用点符号来引用子模块(要执行的文件/脚本)。 我也使用了python3.9+。 所以我既不需要任何init .py 也不需要任何 sys path append 语句。

希望有帮助! 快乐编码!

如果你使用 Anaconda 你可以这样做:

conda develop /Path/To/Your/Modules

从 Shell 开始,它会将您的路径写入 conda.pth 文件到第 3 方模块的标准目录(在我的情况下为站点包)。

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

除了像接受的答案这样的建议解决方案外,我在 Pycharm 中遇到了同样的问题,我不想像上面建议的相对寻址那样修改导入。

我终于发现,如果我在Interpreter settings中将我的src/ (我的 python 代码的根目录)标记为源,问题就会得到解决。

在设置中

在此处输入图像描述

在我的例子中有帮助(包在同一个文件夹中):

import.nameOfPackage

或者

from.nameOfPackage 导入 *

暂无
暂无

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

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