Putting aside whether the use of isinstance is harmful, I have run into the following conundrum when trying to evaluate isinstance after serializing/deserializing an object via Pickle:
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__)
Can anyone shed some light on why isinstance would fail in this situation? In other words, why does Python think these objects are of two different classes? When I remove the second class definition, isinstance
works fine.
Pickle is unsafe because it constructs arbitrary Python objects by invoking arbitrary functions. However, this is also gives it the power to serialize almost any Python object, without any boilerplate or even white-/black-listing (in the common case).
With pickle protocol v1, you cannot pickle open file objects, network connections, or database connections.
Pickle on the other hand is slow, insecure, and can be only parsed in Python. The only real advantage to pickle is that it can serialize arbitrary Python objects, whereas both JSON and MessagePack have limits on the type of data they can write out.
Python pickle module is used for serializing and de-serializing a Python object structure. Any object in Python can be pickled so that it can be saved on disk.
This is how the unpickler works (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
To find and instantiate a class.
So of course if you replace a class with an identically named class, the klass = getattr(mod, name)
will return the new class, and the instance will be of the new class, and so isinstance will fail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With