Python导入-参考顶层模块,而不是“层内”模块

时间:2019-08-28 08:38:13

标签: python django

Python v2.7

目录结构

- project
  - manage.py
  - utils
    - __init__.py
    - somescript.py
  - apps
    - __init__.py
    - someapp
      - views.py
      - utils.py

project.apps.someapp.views

// imports
from utils import somescript

// rest of the stuff

提高ImportError: cannot import name somescript

尝试了点分相对导入:

// imports

from ...utils import somescript

// rest of the stuff

这引起ValueError: Attempted relative import beyond toplevel package

这是一个Django项目。它贯穿manage.py
命令./manage.py runserver 0:41000

2 个答案:

答案 0 :(得分:2)

我有点惊讶,像丹尼尔·罗斯曼(Daniel Roseman)这样的人建议您重命名一个模块,而这个问题早已解决,可以通过__future__ lib为py2中的绝对导入提供支持。

您需要做的就是将此添加到模块顶部(在任何其他语句之前):

from __future__ import absolute_import

从那时起,所有非显式相对导入都将被视为绝对导入(即,在py3中),因此在apps.someapp.views中,您可以执行以下操作:

from __future__ import absolute_import
import utils # => project.utils
from . import utils as local_utils # => apps.someapp.utils

注意:请注意__future__指令仅影响当前模块,其他模块将不受影响。

NB2:您可能也想看看__future__.unicode_literals-在Django项目中,它使大多数地方都希望使用Unicode的工作变得更加轻松。

答案 1 :(得分:0)

正如@Daniel Roseman所建议的,您应该升级到Python 3。

但是,这并不总是可能的,或者至少现在不可能。

有一个Python内置模块imp。您可以使用它来手动导入所需的文件。

这是一个如何工作的示例:

project.apps.someapp.views

import imp
somescript = imp.load_source('utils.somescript', 'path/to/utils/somescript.py')

现在,您可以在somescript中使用views.py。这不是最好的解决方案,但是在准备好将代码库升级到Python 3之前,它可能会帮助您缩小差距。

另外,请注意以灵活的方式指定文件路径,而无需进行硬编码。