[英]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)指向正确的工作目录(即您的项目文件夹)
在我的例子中有帮助(包在同一个文件夹中):
import.nameOfPackage
或者
from.nameOfPackage 导入 *
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.