【问题标题】:Python venv ModuleNotFoundErrorPython venv ModuleNotFoundError
【发布时间】:2018-01-06 18:13:36
【问题描述】:

(在用重复的问题投票给我打分之前,请注意,我在这个问题上能找到的所有内容都与 virtualenv 有关,而不是 venv)

系统

  • Ubuntu 服务器 16.04
  • Python 3.6 已安装,Python 3.5 本机

背景 (人为的例子,所以可能有一两个错字,但想法是重要的部分)

我有一个项目,形式如下:

Project/
├── __init__.py
└── project
    ├── packageA
    │   ├── fileA.py
    │   └── __init__.py
    └── packageB
        ├── fileB.py
        └── __init__.py

在fileb.py中,我有一个导入语句,例如

import project.packageA.fileA

我通过以下方式创建了一个 venv;

cd /path/to/Project; python3.6 -m venv .venv; source .venv/bin/activate

然后我跑

source project/packageB/fileB.py

这会给我一个错误:

ModuleNotFoundError: no module named 'project'

尝试解决

  1. 将“项目”的路径和“项目”的路径添加到 $PATH
  2. 在 .venv/bin/activate 脚本中修改 $PYTHONPATH,使 sys.path 现在指向“Project”和“project”
  3. 完整阅读文档here
  4. 已验证 os.sys.path 显示项目和项目路径

问题:必须可以使用 venv 进行模块导入,否则它的值将为零 - 那么我在设置中根本缺少什么? (对于virtualenv,我只使用了'add2virtualenv')

[编辑 - 显示更多细节]

# Changes to .venv/bin/activate
PYTHONPATH="/home/steve/Temp/Project:/home/steve/Temp/Project/project:$PYTHONPATH"
export PYTHONPATH

python -c "import os; print(os.sys.path)"
['', '/home/steve/Temp/Project', '/home/steve/Temp/Project/project', .....

[Edit2 - 将 packageA 添加到 PYTHONPATH Works]

如果我将 'path/to/packageA' 添加到我的 PYTHONPATH 中,则导入工作。要使用它,我必须将每个子包添加到我的项目中——对于大型项目来说不太理想。

【问题讨论】:

    标签: python python-3.x python-venv


    【解决方案1】:

    这一行

    ​$ source project/packageB/fileB.py
    

    失败是因为

    1. import 路径搞砸了,它包含 project 文件夹,但它不应该
    2. project 可能不在你的 PYTHONPATH

    修复它

    第 1 步)修复 fileB.py 中的 import 语句,将您的 import 替换为

    ​import packageA.fileA
    

    第 2 步)通过检查您的 bash 环境,自己确认是否将 project 添加到 PYTHONPATH

    ​$ echo $PYTHONPATH     # does it contain `path/to/project`?
    

    如果不临时修复它

    ​$ export PYTHONPATH=path/to/project:$PYTHONPATH   # forget `/path/to/Project` you only need `path/to/Project/project`
    

    (注意对$PATH 的更改与Python package/module 搜索无关,因此这是一种浪费的尝试)。

    那么当你运行你的脚本时,它就不会失败:

    $ source project/packageB/fileB.py      # success?!
    

    顺便说一句,最好用python调用你的python脚本:

    $ python project/packageB/fileB.py
    

    最后,通过编辑虚拟环境的bin 目录中的activate 脚本来永久更新您的虚拟环境。在顶部附近的某处添加PYTHONPATH 导出。

    【讨论】:

    • 我的例子被简化了,确实每个包都有一个初始化文件,就像“项目”一样。我的 PYTHON 路径已添加到 venv/bin/activate 文件中。我通过 python -c "import os; print (os.sys.path)" 确认了这一点。我添加了项目和项目。此外,当从 pycharm 中运行时,导入将按原样工作。我会在早上更新细节,但我想我已经涵盖了基础。除非您说对于嵌套包,否则我必须将所有子目录添加到最后一个分支。我真的很感谢你的帮助,顺便说一句……这是在踢我的尾巴。
    • 此外,deets 方法使其可以原样与导入一起使用。此外,使用带有 add2virtualenv 的旧版虚拟环境可以使导入工作。
    • 好的,我已经在我的回答中删除了对 __init__.py 的引用,因为我看到您已将其编辑到您的问题中。
    【解决方案2】:

    恕我直言,情况有点模糊。我对此的解决方案是:为您的项目创建一个 setup.py(无论如何都是有益的),并使用激活的 venv 执行“python setup.py develop”。

    这会将您的项目添加到 PTH 文件中,因此您可以导入。

    setup.py 示例,取自互联网:

    # from http://python-packaging.readthedocs.io/en/latest/minimal.html
    
    from setuptools import setup
    
    setup(name='funniest',
          version='0.1',
          description='The funniest joke in the world',
          url='http://github.com/storborg/funniest',
          author='Flying Circus',
          author_email='flyingcircus@example.com',
          license='MIT',
          packages=['funniest'],
          zip_safe=False)
    

    【讨论】:

    • 感谢您的回答。您是否知道它添加了哪个“PTH”文件?我不能独立于设置添加到同一个文件吗?
    • 好吧,这似乎可行——但它完全是牛船——我不敢相信如果没有一种优雅的方式来处理像进口这样基本的事情,一个工具会被运送——无论如何,你的只是信使,谢谢你让我摆脱束缚。
    • 我不得不承认这对我来说也总是有点麻烦。 OTOH我所做的大多数事情最终都会有一个setup.py,所以......显然virtualenv有一些东西(甚至不知道它)叫做add2virtualenv。最终,venv 可能需要编写 20 行代码——你可以考虑提交一个错误。
    • 至于 pth 文件 - 不知道。只需 grep 浏览站点包并查找您的包路径。
    猜你喜欢
    • 2020-08-03
    • 2022-01-12
    • 2019-06-01
    • 2020-09-09
    • 1970-01-01
    • 2022-01-03
    • 2021-07-05
    • 2021-09-13
    • 1970-01-01
    相关资源
    最近更新 更多