无法在 Python 中导入我自己的模块
Posted
技术标签:
【中文标题】无法在 Python 中导入我自己的模块【英文标题】:Can't import my own modules in Python 【发布时间】:2012-03-12 02:02:59 【问题描述】:我很难理解 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
【问题讨论】:
【参考方案1】:函数import
在您的 PYTHONPATH 环境中查找文件。变量和您的本地目录。因此,您可以将所有文件放在同一目录中,也可以将输入的路径导出到终端::
export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"
【讨论】:
那么我怎样才能确保它适用于其他使用它的人呢?我宁愿不必告诉他们在运行之前设置某些环境变量。 当前目录在 pythonpath 中,所以只要脚本在同一个文件夹/目录中,它应该可以工作。不幸的是,这些脚本中的每一个都位于不同的目录中。 对于 Windows 用户,我们使用“set PYTHONPATH=%PYTHONPATH%;C:\path_to_myapp\myapp\myapp\”代替export
在 vs 代码中,我可以通过将 PYTHONPATH Env 变量添加到我的 launch.json 来解决此问题:"env": "PYTHONPATH": "$workspaceFolder" 【参考方案2】:
在您的特定情况下,您似乎正在尝试从 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。
【讨论】:
我尝试在我的TestCase.py
中简单地使用import
,但它仍然给了我同样的错误。我假设这是因为它在__init__.py
?的子目录中?
哦,等等,我想我明白了。如果我的测试用例是从包中调用的,我可以使用from ... import ...
对吗?
只有在从包外部导入 TestCase 时,您才会这样做——例如,如果我在测试文件夹中运行 from myapp.tests import TestCase from a script outside myapp. If you're running
python TestCase.py`,您将无法进行相对导入
我运行“pip install -e.”来安装 myapp,但是当尝试在 Visual Studio 代码中运行 TestCase 时,我仍然收到“ImportError: No module named myapp”。但是如果我运行“python”,然后在 python 中运行“from myapp import SomeObject”,它就可以工作。我做错了什么?
@DavidRobinson 我使用了你提到的方法,执行from fodername import file_name_of_my_py_code
后没有显示错误,但是当我尝试访问file_name_of_my_py_code.py
中定义的对象时,它说NameError: name 'ClassName' is not defined
【参考方案3】:
导出路径是个好方法。另一种方法是将 .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
【讨论】:
如果我在 Windows 中工作,我该怎么做 我不确定。如果您使用的是 Windows。找一些vm软件,用linux。或者 - 请参阅有关在 Windows 中导出变量的答案。 ***.com/questions/559816/… 这正是我所需要的 很高兴听到@Lee88 - 我自己花了一段时间才弄清楚:)【参考方案4】:你可以试试
from myapp.myapp import SomeObject
因为您的项目名称与 myapp.py 相同,这使得它首先搜索项目文档
【讨论】:
【参考方案5】:在你的第一个 myapp 目录中,你可以添加一个 setup.py 文件并在 setup.py 中添加两个 python 代码
from setuptools import setup
setup(name='myapp')
在命令行的第一个 myapp 目录中,使用 pip install -e 。安装包
【讨论】:
【参考方案6】:在我的情况下,这是 Windows 与 Python 的惊喜,尽管 Windows 文件名不区分大小写,但 Python 导入是。因此,如果您有 Stuff.py
文件,则需要按原样导入此名称。
【讨论】:
【参考方案7】:pip install
在 Windows 10 上默认安装在“Program Files/PythonXX/Lib/site-packages”中,这是一个需要管理权限的目录。所以我通过以管理员身份运行 pip install 解决了我的问题(即使您使用管理员帐户登录,您也必须以管理员身份打开命令提示符)。此外,从 python 调用 pip 更安全。
例如python -m pip install <package-name>
而不是pip install <package-name>
【讨论】:
你成就了我的一天。对于其他人.. 如果您有很多本地模块,这很重要。本地模块被其他本地模块使用,您需要先安装本地模块并将其作为其他模块的导入列表的一部分。很简单,但我花了很长时间才掌握模块概念。【参考方案8】:你需要有
__init__.py
在所有包含您需要与之交互的代码的文件夹中。 即使您尝试导入的文件处于同一级别,您也需要在每次导入时指定项目的***文件夹名称。
【讨论】:
【参考方案9】:假设我写了一个模块
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
【讨论】:
【参考方案10】:简答:
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 语句。
希望对您有所帮助!快乐编码!
【讨论】:
以上是关于无法在 Python 中导入我自己的模块的主要内容,如果未能解决你的问题,请参考以下文章