Loading video player…

Using the pickle Module

00:00 In this lesson, you’re going to test out using pickle on a custom defined class. Here I’ve got a text editor and a terminal open, and the first thing I’m going to do is create a new virtual environment.

00:13 pickle is built into Python, but you’re going to be installing third-party libraries later on, and it’s always a good idea to separate out your environments.

00:21 So once that’s been created, go ahead and activate it.

00:27 Inside a new Python file, which I’ve called pickling.py, you can go ahead and import pickle. If you’ve used the json module, pickle should feel somewhat familiar with its four key methods. There’s a pickle.dump(), a pickle.dumps(), pickle.load(), and pickle.loads().

00:50 As you might imagine, the dump methods will pickle data into a serialized format, and the load methods will convert that serialized format back into the original data type.

01:02 The ones that end in s will either return or load from a byte string object, while the ones that don’t will work with a file type object. So now that this is here, I’m going to go ahead and delete this. Go ahead and define a new class, which you can call example_class.

01:22 This class is going to have a number of properties, so say .a_number, which you can set equal to something like 35; .a_string can be equal to "hey"; a_list , which can be just [1, 2, 3]; a dictionary, which you can make a bit more complex, so you’ll have a "first" key with a value of "a", a "second" with a value of an integer 2, and "third", which you can go ahead and make a list.

01:56 And then finally, go ahead and put in .a_tuple, which can be something like (22, 23). You can see this class here is made up of properties of all sorts of different data types.

02:08 Now that you’ve defined that, you can make an instance of that. So say my_object and this’ll just be example_class() like so. And then if you want to pickle this, go ahead and make a new variable called my_pickled_object and set this equal to pickle.dump—and you’ll want to do the string version of this, so .dumps()—and then pass in my_object.

02:35 Okay. If you want to take a look at what that looks like, you can print it out. So do some f-string formatting and you’ll say f"This is my pickled object:",

02:47 then pass in a newline, and then you can put in f"{my_pickled_object}", and then another newline like so. Okay! So now that my_pickled_object contains the serialized version of your class, go ahead and change it. You can say something like my_object, and then if you access the dictionary property, go ahead and set that equal to None.

03:11 So this would be changing the actual object instance here, so if the pickled object is a true copy, this shouldn’t be changed. To test this out, go ahead and make a new variable and call this my_unpickled_object.

03:27 This will equal pickle, and then you’ll load from a string and pass in my_pickled_object.

03:36 And if you want to see this, you can go ahead and print it out like before. So I’m going to do this over a couple of lines. More f-string formatting, and then because we’re only interested in the .a_dict property of the unpickled object,

03:50 you can go ahead and then just pass in my_unpickled_object like so. Okay! Before we run this, let’s go ahead and take a look. You defined a class here which has a number of properties that are all sorts of different Python data types.

04:06 You then made an instance of this object and pickled it while saving the byte string as this variable.

04:14 You then changed the original object to make one of the properties equal to None, and then you unpickle the byte string, and take a look at that object’s property.

04:26 Let’s go ahead and take a look and try this out.

04:30 Right away, I can see a small issue. We actually only wanted to see the .a_dict property, so where you said my_unpickled_object, just go ahead and access the .a_dict property like so. Let’s go ahead and save that and try to rerun it. Okay!

04:48 Looking at the terminal here and starting from down here, you can see that the pickled object is this byte string and is definitely not human-readable. You can see you have this example_class here, but you can’t really read anything else here. But then when you unpickled it, you can see that the .a_dict was maintained.

05:07 So, {'first': 'a', 'second': 2} and 'third' of the list are still present there—

05:13 which matches what’s up here! So this is a small example, and everything’s pretty static here, but you can see that using pickle, you can create this byte string object, which you can then save and then reload at a later time to maintain the state of that object when you pickled it. All right! In the next lesson, you’re going to see some different protocol formats of the Python pickle module as it’s changed over time.

Avatar image for SatyaRavipati

SatyaRavipati on March 6, 2021

Hello Joe. Thanks for Tutorial. It is very helpful. I didn’t understand how we resolved error at 04:37 when trying to add a member variable for dict. We solved the error because it is Python data type? And is it because we should have a similar class while unpickling with same member variable?

Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on March 8, 2021

@SatyaRavipati It wasn’t an error by itself but rather an unintended behavior. You wanted to confirm if the .a_dict property of the my_object instance did successfully unpickle from the bytes representation. Remember that you assigned it a None value after pickling the object.

However, printing my_object produces the default representation of objects in text:

>>> print(my_object)
<__main__.example_class object at 0x7fdc76c25910>

That isn’t very helpful. By accessing the .a_dict property using the dot notation, you can investigate its value:

>>> print(my_object.a_dict)
{'first': 'a', 'second': 2, 'third': [1, 2, 3]}

This confirms you unpickled the previous state of your object.

Become a Member to join the conversation.