python - Python 3:当本地模块存在同名时导入核心模块?
问题描述
我正在开发一个 Python 3 项目,不幸的是它有一个名为 的本地模块typing
,它与内置typing
模块发生冲突。
这样做的最终结果是我无法导入内置typing
模块,因为首先引用本地typing
模块并typing
以sys.modules
.
我知道我可以将本地模块重命名为其他内容并修复所有引用,如果没有其他选择,我会这样做。问题是我不拥有代码,因此如果我或最终副本的所有者对该文件进行了更改,那么保持我的副本和最终副本同步将变得很棘手。
我想知道是否有办法使用类似模块的东西以不同的名称importlib
导入核心模块?typing
我尝试了几件事,但它们总是失败,因为typing
首先引用本地模块并typing
以sys.modules
. 当存在同名模块时从内置库导入中的一些解决方案看起来很有希望,但由于递归错误而失败。
解决方案
你是对的:更好的解决方案是重命名该模块。在导入系统周围进行黑客攻击可能会导致令人头疼的问题,以及更多的黑客攻击。打破格局:重命名模块,让大家开心。
穷人的解决办法是改变sys.path
顺序。如果您设法将路径放在......./lib/site-packages
包含包含typing
模块的包的目录的路径之前,并且如果您在整个 Python 程序的任何其他模块导入 any之前这样做typing
,它就可以工作。
这是我的设置:
stack_overflow/
├─ annoying/
│ ├─ __init__.py
│ ├─ innocent.py
│ ├─ typing.py
│ ├─ main.py
# file: innocent.py
import typing
print("'typing' imported")
abc: typing.List[str] = ["a", "b", "c"]
# file: main.py
import sys
print(sys.path)
import innocent
并且两者__init__.py
都是typing.py
空的。
当我执行我的主要内容时,我得到:
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
'typing' imported
Traceback (most recent call last):
[...]
AttributeError: module 'typing' has no attribute 'List'
因为导入了错误的文件,由于sys.path
Pythontyping
在annoying
目录中搜索之前在其site-packages
.
我现在把图书馆的路径放在最后:
# file: main.py
import sys
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
打印:
['C:\\PycharmProjects\\stack_overflow\\annoying', ... Python regular stuff ...]
[... Python regular stuff ..., 'C:\\PycharmProjects\\stack_overflow\\annoying']
'typing' imported
现在顺序颠倒了,Python优先typing
从其导入site-packages
,一切都按预期工作。但是,如果我有一个导入(甚至是可传递的)到typing
在我更改之前导入 a 的模块sys.path
,它将再次失败:
# file: main.py
import sys
import innocent # raise AttributeError: module 'typing' has no attribute 'List'
print(sys.path)
annoying_library_index_in_syspath, annoying_library_path = next((i, path) for i, path in enumerate(sys.path))
sys.path.pop(annoying_library_index_in_syspath)
sys.path.append(annoying_library_path)
print(sys.path)
import innocent
但乱搞sys.path
很容易出现错误、冲突、痛苦和悲伤。这就是为什么不鼓励为用户模块重用标准库名称的原因。所以请修复文件,这确实是最好的解决方案。
推荐阅读
- react-native - TypeError:未定义不是函数(评估'store.getState()')
- php - 雄辩的关系和类与构造函数
- r - Rowsums 没有正确添加?
- google-apps - 如何区分谷歌套件管理员和谷歌套件业务管理员之间使用谷歌api
- rest - 使用python将二进制文件上传到API
- c++ - 如何从客户端在 gsoap C++ 的标头中传递非 xml 数据?
- single-sign-on - 在 SAML LogoutRequest 实例中设置会话索引
- android - 如何捏缩放从图库中挑选的图像
- pandas - 熊猫 - 模糊匹配 - 进行模糊匹配时加速循环?
- node.js - Node.js amqplib - 在连接关闭的情况下无法实现重新连接