8

在我写这篇文章时,对我来说,我实际上遇到了这个问题似乎几乎是超现实的。

我有一个对象列表。这些对象中的每一个都是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
4

2 回答 2

14

此错误表明Individual该类以某种方式被创建了两次。您pop[0]使用 的一个版本创建Instance,并且正在使用另一个版本进行检查。尽管它们几乎相同,但 Python 不知道这一点,并且isinstance失败了。要验证这一点,请检查pop[0].__class__ is Individual评估是否为假。

通常类不会被创建两次(除非你使用reload),因为模块只被导入一次,并且所有类对象实际上都是单例的。但是,使用包和相对导入可能会留下一个陷阱,导致模块被导入两次。当脚本(以 开头python bla,而不是从另一个模块导入以import bla)包含相对导入时,就会发生这种情况。运行脚本时,python 不知道它的导入引用包,因此它将其导入处理为绝对的,创建一个具有自己的类Genetic的顶级模块。另一个其他模块正确导入了最终导入的包,这导致创建了分身,.individualindividual.IndividualGeneticGenetic.individualGenetic.individual.Individual

要解决此问题,请确保您的脚本仅使用绝对导入,例如import Genetic.individual即使相对导入import individual似乎工作得很好。如果您想节省打字时间,请使用import Genetic.individual as individual. 另请注意,尽管您使用旧式类,isinstance但应该仍然可以工作,因为它早于新式类。话虽如此,强烈建议切换到新式课程。

于 2012-10-23T21:02:20.697 回答
1

您需要使用继承自的新型类

class ClassName(object):
    pass

从您的示例中,您正在使用继承自的旧式类

class Classname:
    pass

编辑:正如@user4815162342 所说,

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

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

于 2012-10-23T20:54:09.757 回答