暂时不管使用isinstance是否有害,在尝试通过Pickle序列化/反序列化对象后尝试评估isinstance时,我遇到了以下难题:
from __future__ import with_statement import pickle # Simple class definition class myclass(object): def __init__(self, data): self.data = data # Create an instance of the class x = myclass(100) # Pickle the instance to a file with open("c:\\pickletest.dat", "wb") as f: pickle.dump(x, f) # Replace class with exact same definition class myclass(object): def __init__(self, data): self.data = data # Read an object from the pickled file with open("c:\\pickletest.dat", "rb") as f: x2 = pickle.load(f) # The class names appear to match print x.__class__ print x2.__class__ # Uh oh, this fails...(why?) assert isinstance(x2, x.__class__)
任何人都能解释为什么在这种情况下实例会失败吗?换句话说,为什么Python认为这些对象是两个不同的类?当我删除第二个类定义,isinstance
工作正常.
这就是unpickler的工作原理(site-packages/pickle.py):
def find_class(self, module, name): # Subclasses may override this __import__(module) mod = sys.modules[module] klass = getattr(mod, name) return klass
查找并实例化一个类.
所以当然如果你用一个同名的类替换一个类,klass = getattr(mod, name)
它将返回新类,而实例将属于新类,因此isinstance将失败.