How to store self values with Pickle?

Viewed 56
class Player:
    def __init__(self):
        self.money = 0
        self.level = 0
        self.xp = 0
        self.xp_until_level = 20
        self.taxi_car = "Cabbie"
        self.busines = "Нет"
        self.busines_income = 1000
        self.upgrade_cost = 10000
        self.car_speed = 10
        self.car_level = 0
        self.drives_until_new_car = 20

p = Player()

I don’t know how to save self values. I making my text game and saving data is my number one problem.

3 Answers

self values are attributes of your instance. Just pickle your insntace (here p) and it stores all the attributes:

import pickle

class Player:
    def __init__(self):
        self.money = 0
        self.level = 0
        self.xp = 0
        self.xp_until_level = 20
        self.taxi_car = "Cabbie"
        self.busines = "Нет"
        self.busines_income = 1000
        self.upgrade_cost = 10000
        self.car_speed = 10
        self.car_level = 0
        self.drives_until_new_car = 20

p = Player()

pickled = pickle.dumps(p)
new_obj = pickle.loads(pickled)
print(new_obj.taxi_car)  # Cabbie

Storing the class instance to a binary file:

The class instance (or any other object) can be stored to, or read from, a pickled (serialised) binary file for later use or archiving.

For example:

import pickle

# Create a class instance (as you have done).    
p = Player()

# Store the class instance to a file.
with open('./cabbie.p', 'wb') as f:  # <-- Note the 'wb' mode, for write-binary
    pickle.dump(p, f)
    
# Read the class instance from a file.
with open('./cabbie.p', 'rb') as f:  # <-- Note the 'rb' mode, for read-binary
    data = pickle.load(f)
    

Testing:

>>> vars(data)

{'money': 0,
 'level': 0,
 'xp': 0,
 'xp_until_level': 20,
 'taxi_car': 'Cabbie',
 'busines': 'Нет',
 'busines_income': 1000,
 'upgrade_cost': 10000,
 'car_speed': 10,
 'car_level': 0,
 'drives_until_new_car': 20}

Pickle is certainly an option. But you might also consider using ConfigParser. It's built in to the standard library, so you don't have to install another package. The advantage to ConfigParser is that you get a nice ini style file that is easily human readable. Here's some code:

import configparser

class Player:
    def __init__(self):
        self.money = 0
        self.level = 0
        self.xp = 0
        self.xp_until_level = 20
        self.taxi_car = "Cabbie"
        self.busines = "Het"
        self.busines_income = 1000
        self.upgrade_cost = 10000
        self.car_speed = 10
        self.car_level = 0
        self.drives_until_new_car = 20

        self.config=configparser.ConfigParser()

    def save_config(self):
        self.config['default'] = {}   # make blank section 'default'
        self.config['default']['money']                = f'{self.money}'
        self.config['default']['level']                = f'{self.level}'
        self.config['default']['xp']                   = f'{self.xp}'
        self.config['default']['xp_until_level']       = f'{self.xp_until_level}'
        self.config['default']['taxi_car']             = self.taxi_car
        self.config['default']['busines']              = self.busines
        self.config['default']['busines_income']       = f'{self.busines_income}'
        self.config['default']['upgrade_cost']         = f'{self.upgrade_cost}'
        self.config['default']['car_speed']            = f'{self.car_speed}'
        self.config['default']['car_level']            = f'{self.car_level}'
        self.config['default']['drives_until_new_car'] = f'{self.drives_until_new_car}'
        with open('settings.ini', 'w') as fid:
            self.config.write(fid)

    def load_config(self):
        self.config.read('settings.ini')
        self.money                = int(self.config['default']['money'])
        self.level                = int(self.config['default']['level'])
        self.xp                   = int(self.config['default']['xp'])
        self.xp_until_level       = int(self.config['default']['xp_until_level'])
        self.taxi_car             = self.config['default']['taxi_car']
        self.busines              = self.config['default']['busines']
        self.busines_income       = int(self.config['default']['busines_income'])
        self.upgrade_cost         = int(self.config['default']['upgrade_cost'])
        self.car_speed            = int(self.config['default']['car_speed'])
        self.car_level            = int(self.config['default']['car_level'])
        self.drives_until_new_car = int(self.config['default']['drives_until_new_car'])

p = Player()
p.save_config()
p.load_config()
print(dict(p.config['default']))

There is a lot of extra overhead to load/save data into variables. This is what the settings.ini file looks like:

[default]
money = 0
level = 0
xp = 0
xp_until_level = 20
taxi_car = Cabbie
busines = Het
busines_income = 1000
upgrade_cost = 10000
car_speed = 10
car_level = 0
drives_until_new_car = 20
Related