Python“导入为”改变全局命名空间

问题描述 投票:0回答:1

我正在使用我的 pythonizer 工具自动将一些 perl 代码转换为 python。 perl 代码使用 Date::Manip 包,它有一个子模块 Date::Manip::Date。我在生成的代码中使用

Date
变量(我在
builtins
中定义)来保存我定义
Date.Manip
的名称空间。当我导入 Date.Manip.Date 包时,即使我将其作为
_Date_Manip_Date
导入,导入仍然会设置一个全局
Date
变量以防止访问我的
Date
命名空间。我正在寻找有关如何避免此问题的想法。我无法更改子模块的名称。这是重现问题的代码(注意我在这个测试用例中使用
Date
作为字符串而不是名称空间):

# date_issue.py:
import sys
sys.path[0:0] = '.'
import Date.Manip as _Date_Manip

# Date/Manip/__init__.py:
Date = '2023-04-15'
import Date.Manip.Date as _Date_Manip_Date
assert Date == '2023-04-15', f"Date got changed to {Date}"

# Date/Manip/Date.py (empty file)

我在断言上得到这个错误:

AssertionError: Date got changed to <module 'Date.Manip.Date' from '/mnt/c/pythonizer/play/./Date/Manip/Date.py'>

我正在考虑在导入之前保存

Date
的值并在之后恢复它,并且只有在导入的模块名称与任何父命名空间同名时才这样做,但是你有有更好的主意吗?

python import global python-module
1个回答
0
投票

你知道如果你做类似的事情怎么办

import collections.abc

你现在可以写

collections.abc
并下定决心做正确的事了吗?这是
collections
包的模块对象的属性访问。为此,子模块必须作为该对象的
abc
属性可用。

为了让它工作,加载包子模块将该子模块设置为父包的属性。因为模块只在第一次导入时加载,所以这个属性分配发生在第一次导入子模块时,无论导入是什么样子 - 导入中的

as
不会改变这个。

试图搞砸这个是个坏主意。如果属性访问链

Date.Manip.Date
解析为
Date.Manip.Date
模块以外的其他内容,则各种奇怪的东西都会中断。不幸的是,您正在尝试自动翻译用不同语言编写的库,因此您没有选择以不同方式设计库的选项。这只是导致此类自动翻译尝试大多注定失败的众多不兼容性之一。

© www.soinside.com 2019 - 2024. All rights reserved.