[英]How to import standard library module instead of local directory?
I have a local directory named "calendar" with an "__init__.py" file. 我有一个本地目录“ calendar”和一个“ __init__.py”文件。
I want "import calendar" to import the standard library module calendar, and not the module defined by my local directory. 我希望“导入日历”导入标准库模块日历,而不是本地目录定义的模块。
I already tried "from __future__ import absolute_import" and changing PYTHONPATH. 我已经尝试过“从__future__ import absolute_import”并更改PYTHONPATH。
There are Good Reasons I can't just rename the directory. 有很好的理由,我不能只重命名目录。 Really.
真。
The problem is that the current working directory (as either ''
or '.'
, depending on version/platform) is always at the top of sys.path
when you start up Python. 问题在于,当您启动Python时,当前的工作目录(如
''
或'.'
,取决于版本/平台)始终位于sys.path
的顶部。
Using absolute imports makes no difference—that just means to look in sys.path
first, instead of looking for relative imports before falling back to sys.path
. 使用绝对导入没有区别-只是意味着首先查看
sys.path
,而不是在回到sys.path
之前寻找相对的导入。
The right solution is obviously to either (a) rename calendar
, or (b) move it into subpackage of some other package instead of having it at the top level. 显然,正确的解决方案是(a)重命名
calendar
,或(b)将其移至其他软件包的子软件包中,而不是将其置于顶层。 Whatever your Good Reasons are, the Good Reasons for doing the right thing are likely even better. 无论您有什么好的理由,做正确的事情的好的理由都可能更好。
But if you must get around this, there are a few things you can do. 但是,如果您必须解决这个问题,则可以做一些事情。 The simplest is to temporarily munge
sys.path
: 最简单的方法是临时修改
sys.path
:
syspath = sys.path
sys.path = [path for path in sys.path if path.strip('.')]
import calendar
sys.path = syspath
However, no matter what you do, this is going to cause huge problems. 但是,无论您做什么,都会造成巨大的问题。 When you later try to import your local package
calendar
—even if you're doing so from a completely different source file—nothing will happen, because there's already something named calendar
in sys.modules
, so that other source file will just get the stdlib calendar
module instead of your package. 当您以后尝试导入本地软件包
calendar
即使您是从完全不同的源文件中导入,也不会发生任何事情,因为sys.modules
已经有一个名为calendar
的东西,因此其他源文件将只获取stdlib calendar
模块而不是您的软件包。
So you'll also need to rename one or the other on the fly and remove it from sys.modules
. 因此,您还需要即时重命名一个或另一个,然后将其从
sys.modules
删除。 Maybe this: 也许这样:
syspath = sys.path
sys.path = [path for path in sys.path if path.strip('.')]
calmod = sys.modules.get('calendar')
del sys.modules['calendar']
calendar = __import__('calendar')
sys.modules['calendar'] = calmod
sys.path = syspath
And, depending on the order at which your modules get run (which may not be easily predictable, or even deterministic), there's a good chance you'll need similar hackery in the other location. 而且,根据模块运行的顺序(这可能不容易预测,甚至无法确定),很有可能在其他位置需要类似的黑客工具。
(What if you never actually need to import your local package calendar
? Well, in that case you don't have this problem… but then I can't imagine what your Good Reasons could possibly be…) (如果您实际上根本不需要导入本地包
calendar
怎么办?那么,在这种情况下,您就不会遇到这个问题……但是,我无法想象您的好理由可能是……)
As the rest says, the best option is to rename the calendar module into a new module not used by standard library. 就像其他人说的那样,最好的选择是将日历模块重命名为标准库不使用的新模块。
But as a workaround if that's not possible, you could create a another module (visible in the syspath) outside the directory where the local calendar.py
file is placed. 但是,如果无法解决该问题,可以在放置本地
calendar.py
文件的目录之外创建另一个模块(在syspath中可见)。
So if you have a hierarchy like this: 因此,如果您具有这样的层次结构:
project/
__init__.py
app1/
__init__.py
calendar.py
module_in_which_i_want_to_use_python_std_calendar.py
You could create a new module named std_calendar.py
outside apps (outside calendar.py is placed). 您可以在应用外部创建一个名为
std_calendar.py
的新模块(位于calendar.py外部)。 In this file you could import calendar (this will be standard calendar module) 在此文件中,您可以导入日历(这将是标准日历模块)
from calendar import *
And the hierarchy would be: 层次结构为:
project/
__init__.py
std_calendar.py
app1/
__init__.py
calendar.py
module_in_which_i_want_to_use_python_std_calendar.py
In module_in_which_i_want_to_use_python_std_calendar.py
you could use standard calendar with: 在
module_in_which_i_want_to_use_python_std_calendar.py
您可以将标准日历用于:
from project import std_calendar as calendar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.