简体   繁体   English

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

[英]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怎么办?那么,在这种情况下,您就不会遇到这个问题……但是,我无法想象您的好理由可能是……)

You could modify sys.path , import the package, then restore sys.path to its original value. 您可以修改sys.path ,导入包,然后将sys.path恢复为原始值。

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

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.

相关问题 当本地模块屏蔽由外部模块导入的标准库模块时,如何导入外部模块? - How do I import an external module when a local module masks a standard library module imported by the external module? 如何在模块路径中导入标准库而不是同名模块 - How to import standard library instead of same-named module in module path 从Python标准库强制导入模块而不是PYTHONPATH默认值 - Force import module from Python standard library instead of PYTHONPATH default 如何在与Python中标准库中的目录相同的目录中导入模块? - How to import a module in the same directory preferred over those in standard library in Python? 如何从其他目录导入本地模块 - How to import a local module from other directory 如何使python从本地目录而不是site-packages导入名称相同的模块? - How to make python import an identically named module from the local directory instead site-packages? 如何从本地目录而不是 pip 安装的库导入模块? - How to import a module from local directory rather than pip-installed library? 不确定如何从Python标准库导入模块 - Unsure how to import module from Python Standard Library 我可以导入与标准库同名的本地模块吗? - Can I import a local module with the same name as a standard-library one? 当存在具有相同名称的本地模块时,如何在Python中访问标准库模块? - How to access a standard-library module in Python when there is a local module with the same name?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM