python - 模块命名空间中的类问题

标签 python namespaces python-import name-mangling

我在玩 python 的命名空间,我遇到了一些我无法解释的行为。我特别想看看您是否可以使用“from module import *”之类的命令来停止导入类。在一个模块中,称之为moduleA,我有以下内容:

class __hi(object): pass

class hey(object):

    def __init__(self):
        # self.hey = __hi()

然后在另一个模块中,比如说 moduleB,我从 moduleA 中导入了“一切”
from moduleA import *

这具有导入类 'hey' 而不是类 __hi 的预期效果。

现在,当取消注释 '# self.hey = __hi()' 上面的行时,我收到一个我不明白的错误:
"NameError: global name '_hey__hi' is not defined"

看起来 python 已经修改了变量名,因为类名有一个双下划线。谁能解释一下?

这个问题与引用的问题完全不同。在提供的链接帖子中,名称与重整变量所在的类变量重整。这不是我要问的。

编辑:

感谢 vaultah 指出:双下划线在行中的位置无关紧要,它仍然会触发名称修改 - 但有人可以解释为什么会这样吗?这意味着,在上述(高度人为的)情况下,您永远无法将一个类的实例保存在另一个类中。

最佳答案

出现此问题的原因是在类中遇到双下划线时会损坏双下划线。

您的类(class) hey包括行 self.hey = __hi() ,并且因为它在一个类中,所以 __hi被损坏到 _hey__hi ,失败了。

您可以通过替换 __hi 来解决此问题带单下划线 _hi ,或删除下划线,或任何其他方式。您可以在文件完成解析之前退出并销毁名称的块中声明您的助手类:

def create_hey():
    class __hi:
        pass

    x = __hi

    class hey:
        def __init__():
            self.__hi = x()

    return hey

hey = create_hey()

但实际上,这需要大量工作。正如众多评论者所建议的那样,您会更好,只需定义 __all__以便控制可能导入的内容:
__all__ = [ 'hey' ]

关于python - 模块命名空间中的类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35117209/

相关文章:

matlab - 以编程方式返回所有函数的列表

C++,静态与命名空间与单例

Python 在同一文件夹中找不到模块

python - Bokeh 图为空

python - 如何使用 Python post 请求和 Telegram 机器人在 Telegram 上发送具有 InlineKeyboardMarkup 的照片

c# - Xaml WPF MVVM 命名空间和新项目文件夹,InitializeComponent(); StartupUri=

python - 如何从另一个目录导入 .py 文件?

python - 包已安装时出现 ModuleNotFoundError

python - 如何将三个列表转换为字典,其中键取自前两个列表的笛卡尔积,值取自第三个列表

python - conda 卡在 Proceed ([y]/n) 上?在 ipython 控制台中更新软件包时