【问题标题】:Python can't import module from packagePython 无法从包中导入模块
【发布时间】:2019-07-31 11:13:42
【问题描述】:

我有一个带有以下布局的烧瓶宁静项目(为方便起见更改了文件名)

myproject/
    __init__.py
    app.py
    common/
        __init__.py
        util.py
    foo/
        __init__.py
        main.py
        utilities.py

foo/ 只是一个文件夹,其中包含 API 端点之一的代码,我计划在未来添加其他端点,因此我有 common/util.py 文件,其中包含我将与其他 API 一起使用的可重用函数端点。

foo/main.py

from flask_restful import Resource, request

from utilities import Analysis

class Foo(Resource):
    def get(self):      
        pass

foo/utilities.py 中,我的类具有获取一些数据的方法,我将这些类导入foo/main.py 以返回 JSON 响应

foo/utilities.py 中的类也使用来自common/util.py 的一些函数,但是当我尝试从common/util.pyfoo/utilities.py 导入某些内容时,我得到import common.util ModuleNotFoundError: No module named 'common'

这可能是什么原因造成的?我尝试导入各种方式: from common.util import my_func from .common.util import my_func from myproject.common.util import my_func

但没有任何效果。

这是myproject/app.py,以防万一:

from flask import Flask
from flask_restful import Api

from foo.main import Foo

app = Flask(__name__)
api = Api(app)

api.add_resource(Foo, '/Foo')

if __name__ == "__main__":
    app.run()

如果重要的话,我会在激活的 virtualenv 中完成所有这些操作

【问题讨论】:

  • 什么 Python 版本? Py2 和 Py3 对隐式相对导入有不同的规则。
  • @phd 我正在使用 python 3
  • 你安装myproject了吗?或者您只是将foo/main 作为脚本运行而无需安装?在后一种情况下,myprojectsys.path 中不可用,只有目录foo 可用,而且它不是包,因此您不能使用相对导入。
  • 安装是什么意思?我不运行foo/main.py 我运行myproject/app.py 来运行整个API,它运行良好,但common.util 的导入在foo/utilities.py 中失败,为了测试它我运行foo/utilities.py,我得到了我写的错误以上
  • 通过运行python setup.py installpip installmyproject 的副本放入当前Python 的site-packages/ 目录(或任何已经在sys.path 中的目录)。当然你必须有setup.py

标签: python module package virtualenv flask-restful


【解决方案1】:

从 common.util 导入 my_func

在 Python 3 中这是绝对导入,即带有common/ 子目录的目录必须在sys.path 中。在你的情况下,这肯定是一个错误的方法。

从 .common.util 导入 my_func

此导入预计 commonfoo 的子目录,但事实并非如此。

从 myproject.common.util 导入 my_func

这最终是最好的方法,但要使其工作,myproject/ 子目录的父目录必须在sys.path 中。要么安装整个myproject,要么将父目录添加到$PYTHONPATH 环境变量,或者将目录添加到foo/main.py 中的sys.path。比如:

PYTHONPATH=/home/to/parentdir /home/to/parentdir/myproject/foo/main.py

import sys
sys.path.insert(0, '/home/to/parentdir')

/home/to/parentdirmyproject/ 所在的目录。

安装myproject或将其父目录添加到sys.path后,也可以使用相对导入。您需要记住 common 是与 foo 相比的兄弟包,因此导入不能来自 .common 而是来自 ..common

from ..common.util import my_func

【讨论】:

  • 谢谢,它成功了。在myproject/app.py 我在顶部添加了以下内容:import sys sys.path.insert('path/to/parent/of/myproject') 一切都很好。唯一的问题是在foo/utilities.py 中我必须使用像from myproject.common.util import 这样的绝对导入,但暂时可以这样做
  • sys.path.insert(0, 'path/to/parent') 不是sys.path.insert('path/to/parent')
猜你喜欢
  • 2016-07-30
  • 1970-01-01
  • 2020-08-27
  • 2018-11-12
  • 2021-06-24
  • 1970-01-01
  • 2012-12-24
  • 1970-01-01
  • 2013-08-01
相关资源
最近更新 更多