Python - 导入全局/站点包模块而不是本地目录中的同名文件

发布于 2024-10-21 20:42:18 字数 305 浏览 2 评论 0原文

我正在使用 python 和 virtualenv/pip。我通过 pip 安装了一个名为 test_utils 的模块(它是 django-test-utils)。在我的一个 Django 应用程序中,我想导入该模块。但是,我在同一目录中还有另一个文件 test_utils.py 。如果我去import test_utils,那么它将导入这个本地文件。

是否可以让 python 使用非本地/非相对/全局导入?我想我可以重命名我的 test_utils.py,但我很好奇。

I'm using python and virtualenv/pip. I have a module installed via pip called test_utils (it's django-test-utils). Inside one of my django apps, I want to import that module. However I also have another file test_utils.py in the same directory. If I go import test_utils, then it will import this local file.

Is it possible to make python use a non-local / non-relative / global import? I suppose I can just rename my test_utils.py, but I'm curious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

雪花飘飘的天空 2024-10-28 20:42:18

您可以通过更改 sys.path 来切换搜索顺序:

del sys.path[0]
sys.path.append('')

这会将当前目录放在系统搜索路径之后,因此本地文件不会隐藏标准模块。

You can switch the search order by changing sys.path:

del sys.path[0]
sys.path.append('')

This puts the current directory after the system search path, so local files won't shadow standard modules.

夜司空 2024-10-28 20:42:18

我能够强制 python 导入全局的
来自 __future__ 导入绝对导入
在文件的开头(这是 python 3.0 中的默认值)

I was able to force python to import the global one with
from __future__ import absolute_import
at the beginning of the file (this is the default in python 3.0)

弥枳 2024-10-28 20:42:18

我的问题更加复杂:

从具有相同名称的文件导入 global/site-packages 模块

处理 aero the pm recycler 我想访问 pip api,特别是 pip.commands.search.SearchCommand来自源文件 pip.py 中我的适配器类 Pip。

在这种情况下,尝试修改 sys.path 是没有用的,我什至完全擦除 sys.path 并添加文件夹 .../site- packages/pip...egg/ 作为 sys.path 中唯一的项目,但没有运气。

我仍然会得到:

print pip.__package__
# 'aero.adapters' 

我发现了两个最终对我有用的选项,它们应该同样适合你:

使用 __builtin__.__import__() 内置函数

global_pip = __import__('pip.commands.search', {}, {}, ['SearchCommand'], -1)
SearchCommand = global_pip.SearchCommand

读取 文档 不过,建议使用以下方法。

使用 importlib.import_module() __import__ 转换包装器。

文档解释了 import_module() 是一个次要的Python 3.1 的功能子集,有助于轻松从 2.7 过渡到 3.1

from importlib import import_module
SearchCommand = import_module('pip.commands.search').SearchCommand

两个选项都可以完成工作,而 import_module() 肯定感觉更 Pythonic,如果你问我,你会同意吗?

欢乐!

My problem was even more elaborate:

importing a global/site-packages module from a file with the same name

Working on aero the pm recycler I wanted access to the pip api, in particular pip.commands.search.SearchCommand from my adapter class Pip in source file pip.py.

In this case trying to modify sys.path is useless, I even went as far as wiping sys.path completely and adding the folder .../site-packages/pip...egg/ as the only item in sys.path and no luck.

I would still get:

print pip.__package__
# 'aero.adapters' 

I found two options that did eventually work for me, they should work equally well for you:

using __builtin__.__import__() the built-in function

global_pip = __import__('pip.commands.search', {}, {}, ['SearchCommand'], -1)
SearchCommand = global_pip.SearchCommand

Reading the documentation though, suggests using the following method instead.

using importlib.import_module() the __import__ conv wrapper.

The documentation explains that import_module() is a minor subset of functionality from Python 3.1 to help ease transitioning from 2.7 to 3.1

from importlib import import_module
SearchCommand = import_module('pip.commands.search').SearchCommand

Both options get the job done while import_module() definitely feels more Pythonic if you ask me, would you agree?

nJoy!

夜访吸血鬼 2024-10-28 20:42:18

您可以重置 sys.path

import sys
first = sys.path[0]
sys.path = sys.path[1:]
import test_utils
sys.path = first + sys.path

sys.path 的第一个条目是“always”(如“per default”):请参阅 python docs) 当前目录,因此如果删除它,您将执行全局导入。

You could reset your sys.path:

import sys
first = sys.path[0]
sys.path = sys.path[1:]
import test_utils
sys.path = first + sys.path

The first entry of sys.path is "always" (as in "per default": See python docs) the current directory, so if you remove it you will do a global import.

隔纱相望 2024-10-28 20:42:18

由于我的 test_utils 位于 django 项目中,因此我能够 from ..test_utils import ... 导入全局项目。

Since my test_utils was in a django project, I was able to go from ..test_utils import ... to import the global one.

听风念你 2024-10-28 20:42:18

不过,首先,我总是会考虑保持本地文件的名称与任何全局模块名称不匹配,一个简单的解决方法,无需修改“sys.path”,可以将全局模块包含在其他文件中,然后导入此全局模块该文件中的模块。

请记住,该文件必须位于其他文件夹中,然后位于名称与全局模块匹配的文件所在的文件夹中。

例如。
./project/root/workarounds/global_imports.py

import test_utils as tutil

然后在
./project/root/mycode/test_utils.py

from project.root.workarounds.global_imports import tutil
# tutil is global test_utils

# you can also do 
from project.root.workarounds.global_imports import test_utils

Though, in first place, I would always consider keeping the name of local file not matching with any global module name, an easy workaround, without modifying 'sys.path' can be to include global module in some other file and then import this global module from that file.

Remember, this file must be in some other folder then in the folder where file with name matching with global module is.

For example.
./project/root/workarounds/global_imports.py

import test_utils as tutil

and then in
./project/root/mycode/test_utils.py

from project.root.workarounds.global_imports import tutil
# tutil is global test_utils

# you can also do 
from project.root.workarounds.global_imports import test_utils
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文