python namespace:__ main __。类不是package.Class的实例

时间:2013-03-01 14:17:07

标签: python namespaces

考虑你有两个如下定义的python文件。假设一个是通用包(class2),另一个执行特定覆盖并充当可执行文件(class1)。

class1.py:

#!/usr/bin/python
class Test(object):
    pass

class Verificator():
    def check(self, myObject):
        if not isinstance( myObject, Test ):
            print "%s is no instance of %s" % (type(myObject),Test)
        else:
            print "OK!"

if __name__ == '__main__':
    from class2 import getTest

    v = Verificator()
    t = Test()
    v.check(t)
    s = getTest()
    v.check(s)

class2.py:

from class1 import Test
def getTest():
    return Test()

首先检查是否正常,第二次检查失败。原因是t__main__.Testsclass1.Testv.check()检查__main__.Test,但是在一天结束时它是v.check()同一个班,对吧?

有没有办法写class1.Test这样它也接受{{1}}个对象,或者其他任何方式来解决这个问题?

3 个答案:

答案 0 :(得分:6)

如果您打算从其他地方导入class1.py,请将顶级代码(if __name__ == '__main__': ...)完全移到单独的文件中。这样,主文件和class2都可以使用相同的文件class1.Test上课。

做几乎所有事情都会打开一堆蠕虫。虽然您可以通过将isinstance切换到type(myObject).__name__ == ...来解决当前问题,但事实仍然是您的Python进程包含两个Test类,其中只有一个类。其他无法区分的类彼此无关,并且彼此失败issubclass测试。这实际上保证了难以诊断的错误。

编辑
另一种选择是在执行main时从class1显式导入类,如答案中所示。建议更进一步,确保类没有以double形式定义。例如,您可以将if __name__ == '__main__'块移动到文件的开头,并以sys.exit(0)结束:

if __name__ == '__main__':
    import class1, class2
    ... use only the public API with module prefixes ...
    sys.exit(0)

# the rest of the module follows here

答案 1 :(得分:1)

感谢提示,最终帮助我尝试了正确的方向。我刚在这个玩具模型中找到的解决方案是使用导入修复命名空间问题。为了排除user4815162342指出的问题,我在class1中添加了另一个类。 class1.py的以下代码似乎可以做,我想要的是:

#!/usr/bin/python
class Test(object):
    pass

class Toast(object):
    pass

class Verificator():
    def check(self, myObject):
        if not isinstance( myObject, Test ):
            print "NOPE: %s is no instance of %s" % (type(myObject),Test)
        else:
            print "OK: %s is instance of %s" % (type(myObject),Test)

if __name__ == '__main__':
    from class2 import getTest
    from class1 import Test, Toast

    v = Verificator()
    t = Test()
    v.check(t)
    t = getTest()
    v.check(t)
    t = Toast()
    v.check(t)

答案 2 :(得分:-2)

你可以使用type()函数(事实上,你会发现这个调用很常见!):

#!/usr/bin/python
class Test(object):
    pass

class Verificator():
    def check(self, myObject):
        if not isinstance( type(myObject), type(Test) ):
            print "%s is no instance of %s" % (type(myObject),Test)
        else:
            print "OK!"

if __name__ == '__main__':
    from class2 import getTest

    v = Verificator()
    t = Test()
    v.check(t)
    s = getTest()
    v.check(s)

可能更糟的解决方案:

if not isinstance( myObject.__class__, Test.__class__ ):  # Use __class__ here.

他们当然是等价的,但除非你迫切需要,否则需要使用双下划线成员才被视为不良形式!但是,它值得了解它们的存在,因此我将这个包含在我的答案中。

请注意,据我所知,这种情况会发生,因为当您运行python class1.py时,class1.py将没有模块。因此,python会将所有内容放入__main__模块中。当您从任何其他脚本导入时,不是 的情况,因此将__main__模块中的某些内容视为特殊情况实际上就是这种情况!