情况: - 我的project_folder中有一个名为calendar的模块 - 我想使用Python库中的内置Calendar类 - 当我使用日历导入日历时,它会抱怨,因为它试图从我的模块加载 .
我做了一些搜索,似乎无法找到问题的解决方案 .
-
How to access a standard-library module in Python when there is a local module with the same name?
-
How to avoid writing the name of the module all the time when importing a module in python?
任何想法,而无需重命名我的模块?
5 回答
更改导入路径:
无需更改模块的名称 . 相反,您可以使用absolute_import来更改导入行为 . 例如,使用stem/socket.py我导入套接字模块,如下所示:
这仅适用于Python 2.5及更高版本;它的启用行为是Python 3.0及更高版本中的默认行为 . Pylint会抱怨代码,但它完全有效 .
解决这个问题的唯一方法就是自己劫持内部进口机器 . 这并不容易,而且充满了危险 . 你应该不惜一切代价避免使用圣杯形状的灯塔,因为危险太危险了 .
重命名您的模块 .
如果你想学习如何劫持内部导入机制,你可以在这里找到如何做到这一点:
The Importing Modules section of the Python 2.7 documentation
The Importing Modules section of the Python 3.2 documentation
PEP 302 - New Import Hooks
有时候有充分的理由陷入这种危险之中 . 你给出的理由不在其中 . 重命名您的模块 .
如果您采取危险的路径,您将遇到的一个问题是,当您加载模块时,它最终会得到一个'official name',这样Python就可以避免再次解析该模块的内容 . 可以在
sys.modules
中找到模块的'official name'到模块对象本身的映射 .这意味着,如果您在一个地方
import calendar
,那么导入的任何模块都将被视为具有官方名称calendar
的模块以及其他任何地方的所有其他尝试import calendar
,包括在其他代码中属于主Python库的模块,将获得该模块日历 .有可能使用Python 2.x中的imputil module来设计客户导入器,导致从某些路径加载的模块首先查找他们导入的模块,而不是首先查找
sys.modules
之类的东西 . 但无论如何,_330582_在Python 3.x中工作 .你可以做一件非常丑陋和可怕的事情,不涉及钩住进口机制 . 这是你可能不应该做的事情,但它可能会奏效 . 它将您的
calendar
模块转换为系统日历模块和日历模块的混合体 . 感谢Boaz Yaniv为skeleton of the function I use . 把它放在calendar.py
文件的开头:我想提供我的版本,这是Boaz Yaniv和Omnifarious的解决方案的组合 . 它将导入模块的系统版本,与以前的答案有两个主要区别:
支持'dot'表示法,例如 . package.module
是系统模块上import语句的替代品,这意味着您只需要替换那一行,如果已经对模块进行了调用,它们将按原样运行
把它放在可以访问的地方,这样你就可以调用它(我的__init__.py文件中有我的):
示例
我想导入mysql.connection,但我有一个本地包已经叫mysql(官方的mysql实用程序) . 所以为了从系统mysql包中获取连接器,我将其替换为:
有了这个:
结果
实际上,解决这个问题相当容易,但实现总是有点脆弱,因为它取决于python导入机制的内部结构,并且在未来版本中它们可能会发生变化 .
(以下代码显示了如何加载本地和非本地模块以及它们如何共存)
如果可能,最佳解决方案是避免使用与标准库或内置模块名称相同的名称命名模块 .