1

I need to protect a class variable. But what to do if the class supports save and load options?

import numpy as np
import pickle
class data(object):
    def __init__(self):
        self.__a = range(100)

    @property    
    def a(self):
         return self.__a

    def save(self, path):
        pickle.dump(self,open(path, 'wb'), protocol=2)

    def load(self, path):
        obj = pickle.load(open(path, 'wb'))
        self.__a = obj.a

This is simple but __aattribute is no more protected because calling instance.a returns the exact instance.__a list and it can changed from the outside which is dangerous in my case.

is there any way around this?

shx2
  • 61,779
  • 13
  • 130
  • 153
Cobry
  • 4,348
  • 8
  • 33
  • 49

2 Answers2

1

To protect lists from being changed, you can return a copy of the list by your property:

@property
def a(self):
    return list(self.__a)
Daniel
  • 42,087
  • 4
  • 55
  • 81
0

Instead of non-standard save/load methods, stick with the standard pythonic way of pickling objects, i.e. using pickle.dump and pickle.load directly.

The data members will be as protected after loading as they were before dumping, i.e. your object behaves the same.

class data(object):
    def __init__(self):
        self.__a = range(100)
    @property    
    def a(self):
         return self.__a

obj = data()
# when you want to save, do:
x = pickle.dumps(obj)
# and for loading, do:
obj = pickle.loads(x)
obj.__dict__
=> {'_data__a': [0,
  1,
  2,
  3,
  ...
]} 

This approach has many advantages, e.g. you can safely pickle objects which reference instances of your class data.

shx2
  • 61,779
  • 13
  • 130
  • 153