简体   繁体   English

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

[英]Proper use of `isinstance(obj, class)`

As I write it, it seems almost surreal to me that I'm actually experiencing this problem. 在我写这篇文章的时候,对我来说,我实际上遇到了这个问题。

I have a list of objects. 我有一个对象列表。 Each of these objects are of instances of an Individual class that I wrote. 这些对象中的每一个都是我编写的Individual类的实例。

Thus, conventional wisdom says that isinstance(myObj, Individual) should return True . 因此,传统观点认为isinstance(myObj, Individual)应该返回True However, this was not the case. 但事实并非如此。 So I thought that there was a bug in my programming, and printed type(myObj) , which to my surprise printed instance and myObj.__class__ gave me Individual ! 所以我认为我的编程中存在一个错误,并且打印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

I'm stumped! 我很难过! What gives? 是什么赋予了?

EDIT : My Individual class 编辑 :我的个人课程

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

This error indicates that the Individual class somehow got created twice. 此错误表示Individual类以某种方式创建了两次。 You created pop[0] with one version of Instance , and are checking for instance with the other one. 您使用一个版本的Instance创建了pop[0] ,并且正在检查另一个版本的Instance Although they are pretty much identical, Python doesn't know that, and isinstance fails. 尽管它们几乎完全相同,但Python并不知道,并且isinstance失败。 To verify this, check whether pop[0].__class__ is Individual evaluates to false. 要验证这一点,请检查pop[0].__class__ is Individual评估为false。

Normally classes don't get created twice (unless you use reload ) because modules are imported only once, and all class objects effectively remain singletons. 通常,类不会被创建两次(除非您使用reload ),因为模块只导入一次,并且所有类对象都有效地保留单例。 However, using packages and relative imports can leave a trap that leads to a module being imported twice. 但是,使用包和相对导入可能会留下导致模块导入两次的陷阱。 This happens when a script (started with python bla , as opposed to being imported from another module with import bla ) contains a relative import. 当脚本(以python bla启动,而不是从具有import bla其他模块import bla )包含相对导入时,会发生这种情况。 When running the script, python doesn't know that its imports refer to the Genetic package, so it processes its imports as absolute, creating a top-level individual module with its own individual.Individual class. 在运行脚本时,python不知道它的导入是否引用了Genetic包,因此它将其导入作为绝对进程处理,创建一个具有自己individual.Individual的顶级individual模块。 individual.Individual类。 Another other module correctly imports the Genetic package which ends up importing Genetic.individual , which results in the creation of the doppelganger, Genetic.individual.Individual . 另一个模块正确导入Genetic包,最终导入Genetic.individual ,这导致了doppelganger, Genetic.individual.Individual的创建。

To fix the problem, make sure that your script only uses absolute imports, such as import Genetic.individual even if a relative import like import individual appears to work just fine. 要解决此问题,请确保您的脚本仅使用绝对导入,例如import Genetic.individual即使像import individual这样的相对导入似乎也能正常工作。 And if you want to save on typing, use import Genetic.individual as individual . 如果您想节省打字,请使用import Genetic.individual as individual Also note that despite your use of old-style classes, isinstance should still work, since it predates new-style classes. 另请注意,尽管使用了旧式类,但isinstance仍然可以工作,因为它早于新式类。 Having said that, it would be highly advisable to switch to new-style classes. 话虽如此,切换到新式课程是非常明智的。

You need to use new-style classes that inherit from 您需要使用继承的新式类

class ClassName(object):
    pass

From your example, you are using old-style classes that inherit from 从您的示例中,您使用的是继承自的旧式类

class Classname:
    pass

EDIT: As @user4815162342 said, 编辑:正如@ user4815162342所说,

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

is caused by using an old-style class, but this is not the cause of your issues with isinstance . 是因使用旧式类,但是这不是你的问题的原因isinstance You should instead make sure you don't create the class in more than one place, or if you do, use distinct names. 您应该确保不要在多个位置创建类,或者如果您这样做,请使用不同的名称。 Importing it more than once should not be an issue. 不止一次导入它应该不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM