繁体   English   中英

如何导入标准库模块而不是本地目录?

[英]How to import standard library module instead of local directory?

我有一个本地目录“ calendar”和一个“ __init__.py”文件。

我希望“导入日历”导入标准库模块日历,而不是本地目录定义的模块。

我已经尝试过“从__future__ import absolute_import”并更改PYTHONPATH。

有很好的理由,我不能只重命名目录。 真。

问题在于,当您启动Python时,当前的工作目录(如'''.' ,取决于版本/平台)始终位于sys.path的顶部。

使用绝对导入没有区别-只是意味着首先查看sys.path ,而不是在回到sys.path之前寻找相对的导入。

显然,正确的解决方案是(a)重命名calendar ,或(b)将其移至其他软件包的子软件包中,而不是将其置于顶层。 无论您有什么好的理由,做正确的事情的好的理由都可能更好。


但是,如果您必须解决这个问题,则可以做一些事情。 最简单的方法是临时修改sys.path

syspath = sys.path
sys.path = [path for path in sys.path if path.strip('.')]
import calendar
sys.path = syspath

但是,无论您做什么,都会造成巨大的问题。 当您以后尝试导入本地软件包calendar即使您是从完全不同的源文件中导入,也不会发生任何事情,因为sys.modules已经有一个名为calendar的东西,因此其他源文件将只获取stdlib calendar模块而不是您的软件包。

因此,您还需要即时重命名一个或另一个,然后将其从sys.modules删除。 也许这样:

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

而且,根据模块运行的顺序(这可能不容易预测,甚至无法确定),很有可能在其他位置需要类似的黑客工具。

(如果您实际上根本不需要导入本地包calendar怎么办?那么,在这种情况下,您就不会遇到这个问题……但是,我无法想象您的好理由可能是……)

您可以修改sys.path ,导入包,然后将sys.path恢复为原始值。

import sys
original_path = sys.path
sys.path = original_path[1:]
import calendar
sys.path = original_path

就像其他人说的那样,最好的选择是将日历模块重命名为标准库不使用的新模块。

但是,如果无法解决该问题,可以在放置本地calendar.py文件的目录之外创建另一个模块(在syspath中可见)。

因此,如果您具有这样的层次结构:

project/
   __init__.py
   app1/
      __init__.py
      calendar.py
      module_in_which_i_want_to_use_python_std_calendar.py

您可以在应用外部创建一个名为std_calendar.py的新模块(位于calendar.py外部)。 在此文件中,您可以导入日历(这将是标准日历模块)

from calendar import *

层次结构为:

project/
   __init__.py
   std_calendar.py
   app1/
      __init__.py
      calendar.py
      module_in_which_i_want_to_use_python_std_calendar.py

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.

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