简体   繁体   English

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

[英]Python Imports - Reference Top Level Module Instead of the “In-Level” Module

Python v2.7 Python v2.7

Directory Structure : 目录结构

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

project.apps.someapp.views : project.apps.someapp.views

// imports
from utils import somescript

// rest of the stuff

Raises ImportError: cannot import name somescript 引发ImportError: cannot import name somescript

Tried a dotted relative import: 尝试了点分相对导入:

// imports

from ...utils import somescript

// rest of the stuff

This raises ValueError: Attempted relative import beyond toplevel package . 这会引发ValueError: Attempted relative import beyond toplevel package

This is a Django project. 这是一个Django项目。 It runs through manage.py . 它通过manage.py运行。
Command : ./manage.py runserver 0:41000 命令./manage.py runserver 0:41000

I'm a bit suprised someone like Daniel Roseman advise you to rename one of your modules when this issue has long been solved by providing support for absolute imports in py2 via the __future__ lib. 我有点惊讶,像Daniel Roseman这样的人建议您通过长期支持__future__ lib来支持py2中的绝对导入的方式解决这个问题,从而重命名您的模块之一。

All you need is to add this at the top of your module (before any other statement): 您需要做的就是将其添加到模块顶部(在任何其他语句之前):

from __future__ import absolute_import

From there on, all non explicitely relative imports will be treated as absolute (ie as in py3), so in apps.someapp.views, you can do: 从那以后,所有非显式相对导入都将被视为绝对导入(即,在py3中),因此在apps.someapp.views中,您可以执行以下操作:

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

NB: note that __future__ directives only affect the current module, your other modules will remain unaffected. 注意:注意__future__指令仅影响当前模块,其他模块将不受影响。

NB2: you may want to have a look at __future__.unicode_literals too - it makes life much easier in django projects which mostly expect unicode everywhere. NB2:您可能也想看看__future__.unicode_literals它使django项目的工作更加轻松,而django项目通常都希望在任何地方使用unicode。

As @Daniel Roseman suggested you should upgrade to Python 3. 正如@Daniel Roseman所建议的那样,您应该升级到Python 3。

However this isn't always possible, or at least not possible right now. 但是,这并不总是可能的,或者至少现在不可能。

There is a Python built-in module imp . 有一个Python内置模块imp You can use it to manually import the files you need. 您可以使用它来手动导入所需的文件。

Here is an example how it could work: 这是一个示例它如何工作的:

project.apps.someapp.views

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

Now you can use somescript in your views.py . 现在您可以在views.py使用somescript了。 It's not the nicest solution, but it might help you to bridge the gap until you're ready to upgrade your codebase to Python 3. 这不是最好的解决方案,但它可能会帮助您弥合差距,直到您准备好将代码库升级到Python 3为止。

Also please take care to specify the filepath in a flexible way, without hard coding. 另外,请注意以灵活的方式指定文件路径,而无需进行硬编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM