正确使用`isinstance(obj,class)`

时间:2012-10-23 20:53:09

标签: python class isinstance

在我写这篇文章的时候,我实际上遇到了这个问题,这似乎是一种超现实主义。

我有一个对象列表。这些对象中的每一个都是我写的Individual类的实例。

因此,传统观点认为isinstance(myObj, Individual)应该返回True。但事实并非如此。所以我认为我的编程中存在一个错误,并打印type(myObj),令我惊讶的是打印instancemyObj.__class__给了我Individual

>>> type(pop[0])
<type 'instance'>
>>> isinstance(pop[0], Individual) # with all the proper imports
False
>>> pop[0].__class__
Genetic.individual.Individual

我很难过!是什么给了什么?

编辑:我的个人课程

class Individual:
    ID = count()
    def __init__(self, chromosomes):
        self.chromosomes = chromosomes[:]    # managed as a list as order is used to identify chromosomal functions (i.e. chromosome i encodes functionality f)
        self.id = self.ID.next()

    # other methods

2 个答案:

答案 0 :(得分:14)

此错误表示Individual类以某种方式创建了两次。您使用pop[0]的一个版本创建了Instance,并且正在检查另一个版本的isinstance。虽然它们非常相似,但Python并不知道,pop[0].__class__ is Individual失败了。要验证这一点,请检查reload是否评估为false。

通常,类不会被创建两次(除非您使用python bla)因为模块只导入一次,并且所有类对象都有效地保留单例。但是,使用包和相对导入可能会留下导致模块导入两次的陷阱。当脚本(以import bla启动而不是从具有Genetic的其他模块导入)包含相对导入时,会发生这种情况。运行脚本时,python不知道其导入引用了individual包,因此它将其导入作为绝对处理,创建了一个顶级individual.Individual模块,其中包含Genetic个模块。类。另一个模块正确导入最终导入Genetic.individual的{​​{1}}包,这会导致创建doppelganger Genetic.individual.Individual

要解决此问题,请确保您的脚本仅使用绝对导入,例如import Genetic.individual,即使像import individual这样的相对导入似乎也能正常工作。如果您想节省打字,请使用import Genetic.individual as individual。另请注意,尽管使用了旧式类,isinstance仍然可以使用,因为它早于新式类。话虽如此,切换到新式课程是非常明智的。

答案 1 :(得分:1)

您需要使用从

继承的新式类
class ClassName(object):
    pass

从您的示例中,您使用的是从

继承的旧式类
class Classname:
    pass

编辑:正如@ user4815162342所说,

>>> type(pop[0])
<type 'instance'>

是由使用旧式类引起的,但这不是isinstance问题的原因。您应该确保不要在多个位置创建类,或者如果您这样做,请使用不同的名称。不止一次导入它应该不是问题。