我正在玩python的命名空间,我遇到了一些我无法解释的行为。特别是我想知道你是否可以使用像'from module import *'这样的命令来停止导入类。在一个模块中,将其命名为moduleA,我有以下内容:
class __hi(object): pass
class hey(object):
def __init__(self):
# self.hey = __hi()
然后在另一个模块中,比如moduleB,我使用
从moduleA导入'everything'from moduleA import *
这具有导入类'hey'但不类__hi的预期效果。
现在当取消注释'#self.hey = __hi()'上面的行时,我得到一个我不明白的错误:
"NameError: global name '_hey__hi' is not defined"
看起来python已经破坏了变量名,因为类名有一个双下划线。谁能解释一下呢?
这个问题与引用的问题完全不同。在链接的帖子中,名称被修改了变量所在的类变量。这不是我要问的。
编辑:
感谢vaultah指出:无论双线下划线在哪里,它仍然会触发名称错位 - 但有人可以解释为什么会这样吗?这意味着,在如上所述的(高度设计的)情境中,你永远不能在另一个类中保存一个类的实例。
答案 0 :(得分:0)
出现此问题的原因是,当在类中遇到双下划线时,它们会被损坏 。
您的班级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' ]