【问题标题】:Django absolute importsDjango 绝对导入
【发布时间】:2019-04-29 15:37:44
【问题描述】:

假设有一个名为foobar 的系统范围模块和一个名为foobar 的django 应用程序,我无法编辑它们,因为它们是外部项目。

现在,我想使用系统 foobar 模块,而不是应用程序,但它不起作用:

$ python --version
Python 2.7.3

$ ./manage.py --version
1.3.1

$ ./manage.py shell
>>> import foobar
>>> print (foobar)
<module 'foobar' from '/path/to/myproject/foobar/__init__.pyc'>

我该怎么办?我想我会改用&lt;module 'foobar' from '/usr/lib/python2.7/dist-packages/foobar/__init__.pyc'&gt;

【问题讨论】:

  • 我是否理解正确 - 您已通过将外国应用程序解压缩到您的项目文件夹中来安装它?那你为什么要通过 import foobar 来使用它,而不是 import myproject.foobar?
  • foobar 应用程序更像是一个子模块。问题是我无法编辑它,我正在寻找如何导入系统模块,而不是应用程序。

标签: python django import module package


【解决方案1】:

Python 在环境变量PYTHONPATH 中定义的位置查找包。你可以很容易地在 Python 中修改它:

https://docs.python.org/2/install/index.html#modifying-python-s-search-path

您需要更改sys.path,以便包含系统 foobar 模块的目录应用程序目录之前。

假设您的 sys.path 看起来像:

>>> import sys
>>> sys.path
['', '/usr/local/lib/python2.7/site-packages']

foobar 位于当前工作目录(用'' 表示)和系统site-packages 目录中,您想让系统foobar 更靠近列表的前面:

>>> sys.path.insert(0, '/usr/local/lib/python2.7/site-packages/foobar')
>>> sys.path
['/usr/local/lib/python2.7/site-packages/foobar', 
 '', '/usr/local/lib/python2.7/site-packages']

请注意,此路径更改仅适用于 Python 的正在运行的进程/实例(在本例中为交互式会话),以后的进程将使用原始路径启动。

不修改路径的解决方案

如果不能或不想修改sys.path,可以使用imp模块手动导入模块:

import imp

name = 'foobar'
path = '/usr/local/lib/python2.7/site-packages/foobar'

fp, pathname, description = imp.find_module(name, path)
try:
    imp.load_module(name, fp, pathname, description)
finally:
    # Make sure the file pointer was closed:
    if fp:
        fp.close()

仅临时修改路径的解决方案

这个解决方案不需要提前知道系统foobar包在哪里,只需要当前目录中不在的那个:

import imp
import sys

# Temporarily remove the current working directory from the path:
cwd = sys.path.pop(0)

# Now we can import the system `foobar`:
import foobar

# Put the current working directory back where it belongs:
sys.path.insert(0, cwd)

【讨论】:

  • 在这种情况下,我只需要加载系统范围的 foobar,通常我会处理 foobar 应用程序。另外,改变整个路径可能会带来我无法控制的副作用。你的解决方案是不是有点过分了?
  • 另外,我使用交互式会话只是为了解释我的问题,但我需要一个真正的 django 应用程序文件中的解决方案。
  • 您的第二个解决方案似乎令人满意,但艰难的道路很烦人。它可能因操作系统或 python 版本而异。
  • 很公平!我添加了另一个不需要硬编码路径的可能解决方案。
【解决方案2】:

试试这个,没有硬代码路径

import os
import sys
PROJECT_DIR = os.path.dirname(__file__) 
# make sure the path is right, it depends on where you put the file is

# If PROJECT_DIR in sys.path, remove it and append to the end.
syspath = sys.path
syspath_set = set(syspath)
syspath_set.discard(PROJECT_DIR)
sys.path = list(syspath_set)

sys.path.append(PROJECT_DIR)

# Then try
import foobar

# At last, change it back, prevent other import mistakes
sys.path = syspath

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 2023-02-06
    • 2023-04-03
    • 2016-10-09
    • 1970-01-01
    相关资源
    最近更新 更多