Joseph
Joseph

Reputation: 55

Is there a way to save multiple variables in python pickle?

I am trying to save multiple variables to a file. E.G saving an item in a shop so I'm trying to save the items price,name and code to one file, and multiple items to the same file

def enter_item_info():
count = 0
count1 = 0
print("how many items are you entering?")
amount = int(input("Items = "))
data = [[0,1,2]] * amount




file = (open('fruit.txt','wb'))
while count < amount:




    data[0 + count1][0] = input("Code")


    data[0 + count1][1] = input("NAme")

    data[0 + count1][2] = input("Price")
    count1 = count1 + 1
    count = count + 1


    print("")



pickle.dump(data , file)
file.close()
amount = str(amount)
file1 = (open('amount.txt','wb'))
pickle.dump(amount , file1)
file1.close()

Upvotes: 4

Views: 9687

Answers (3)

root
root

Reputation: 2428

Preserve variable names

The other answers rely on the list/order of variables during saving to be consistent with their list during loading. That might not be the case due to a bug/typo in that list or due to loading a file that was created with an older version of the code before that list changed.

A safer solution is to save the variable names as well. That way, the saved variable names are used instead of assuming what the variable names are.

import pickle
import inspect

def save_vars(filename, var_names):
    '''
    Save several variables to a pickle file
    such that their variable names can be recovered.
    Usage: `save_vars('variables.pkl', ['a', 'b'])`
    '''
    caller_vars = inspect.stack()[1].frame.f_locals
    saved_vars = {var_name: caller_vars[var_name] for var_name in var_names} # to skip missing ones, add `if var_name in caller_vars`
    with open(filename, 'wb') as f:
        pickle.dump(saved_vars, f)

def load_vars(filename):
    caller_vars = inspect.stack()[1].frame.f_locals
    with open(filename, 'rb') as f:
        saved_vars = pickle.load(f)
    caller_vars.update(saved_vars)

Example usage:

a, b = 1, 2
save_vars('variables.pkl', ['a', 'b'])
del a, b
load_vars('variables.pkl')

This can be extended to globals() variables if needed.

load_vars() can optionally be modified such that it loads only a user-specified subset of the variables or renames them.

Upvotes: 0

Mike McKerns
Mike McKerns

Reputation: 35207

You definitely can save multiple objects to a pickle file, either by putting the objects in a collection (like a list or dict) and then pickling the collection, or by using multiple entries in a pickle file… or both.

>>> import pickle
>>> fruits = dict(banana=0, pear=2, apple=6)
>>> snakes = ['cobra', 'viper', 'rattler']
>>> with open('stuff.pkl', 'wb') as f:
...   pickle.dump(fruits, f)
...   pickle.dump(snakes, f)
... 
>>> with open('stuff.pkl', 'rb') as f:
...   food = pickle.load(f)
...   pets = pickle.load(f)
... 
>>> food
{'pear': 2, 'apple': 6, 'banana': 0}
>>> pets
['cobra', 'viper', 'rattler']
>>> 

Upvotes: 14

SylvainD
SylvainD

Reputation: 1763

From the documentation (emphasis on the ==>):

The following types can be pickled:

None, True, and False
integers, long integers, floating point numbers, complex numbers
normal and Unicode strings
===> tuples, lists, sets, and dictionaries containing only picklable objects
functions defined at the top level of a module
built-in functions defined at the top level of a module
classes that are defined at the top level of a module
instances of such classes whose __dict__ or the result of calling __getstate__() is picklable (see section The pickle protocol for details).

So you can store all your data in lists and/or dictionnary and you should be fine.

Upvotes: 1

Related Questions