[英]Proper use of `isinstance(obj, class)`
在我写这篇文章的时候,对我来说,我实际上遇到了这个问题。
我有一个对象列表。 这些对象中的每一个都是我编写的Individual
类的实例。
因此,传统观点认为isinstance(myObj, Individual)
应该返回True
。 但事实并非如此。 所以我认为我的编程中存在一个错误,并且打印type(myObj)
,令我惊讶的打印instance
和myObj.__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
此错误表示Individual
类以某种方式创建了两次。 您使用一个版本的Instance
创建了pop[0]
,并且正在检查另一个版本的Instance
。 尽管它们几乎完全相同,但Python并不知道,并且isinstance
失败。 要验证这一点,请检查pop[0].__class__ is Individual
评估为false。
通常,类不会被创建两次(除非您使用reload
),因为模块只导入一次,并且所有类对象都有效地保留单例。 但是,使用包和相对导入可能会留下导致模块导入两次的陷阱。 当脚本(以python bla
启动,而不是从具有import bla
其他模块import bla
)包含相对导入时,会发生这种情况。 在运行脚本时,python不知道它的导入是否引用了Genetic
包,因此它将其导入作为绝对进程处理,创建一个具有自己individual.Individual
的顶级individual
模块。 individual.Individual
类。 另一个模块正确导入Genetic
包,最终导入Genetic.individual
,这导致了doppelganger, Genetic.individual.Individual
的创建。
要解决此问题,请确保您的脚本仅使用绝对导入,例如import Genetic.individual
即使像import individual
这样的相对导入似乎也能正常工作。 如果您想节省打字,请使用import Genetic.individual as individual
。 另请注意,尽管使用了旧式类,但isinstance
仍然可以工作,因为它早于新式类。 话虽如此,切换到新式课程是非常明智的。
您需要使用继承的新式类
class ClassName(object):
pass
从您的示例中,您使用的是继承自的旧式类
class Classname:
pass
编辑:正如@ user4815162342所说,
>>> type(pop[0])
<type 'instance'>
是因使用旧式类,但是这不是你的问题的原因isinstance
。 您应该确保不要在多个位置创建类,或者如果您这样做,请使用不同的名称。 不止一次导入它应该不是问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.