【问题标题】:Can't import my own modules in Python无法在 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

【问题讨论】:

    标签: python import module package


    【解决方案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 中导出变量的答案。 stackoverflow.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 语句。

              希望对您有所帮助!快乐编码!

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-11-11
                • 1970-01-01
                • 2016-05-14
                • 2018-06-21
                • 1970-01-01
                • 2021-05-18
                • 2018-12-06
                • 1970-01-01
                相关资源
                最近更新 更多