Reputation: 5968
I would like a class that in its initialize checks if filename
exists. If it does it should initialize itself with filename
, otherwise it should run init. At a later point I can then run a save
method, saving the entire object.
A sketch of what I want:
class data(object):
def __init__(self, filename):
if does_not_exist(filename): # create new
[... expensive computations]
self.save(filename)
else: # load existing
with open(filename,'rb') as fp:
self = pickle.load(fp)
def save(self, filename):
with open(filename,'wb') as fp:
pickle.dump(self, fp)
When loading I know that I can do something like
tmp = pickle.load(fp)
self.a = tmp.a
self.b = tmb.b
...
But I hope that there is a better way
I assume this question has been asked before, but couldn't find it :/
Upvotes: 0
Views: 1175
Reputation: 2973
Assigning to self
within __init__
is meaningless, since you're not modifying the object that self
points to -- you're just binding the variable name self
in the function to a different object.
What you can do instead is use a staticmethod
or classmethod
to perform the optional loading from cache:
class Data(object):
@classmethod
def init_cached(cls, filename):
if not os.path.exists(filename): # create new
result = cls(filename)
result.save(filename)
return result
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename):
pass # [... expensive computations]
Now, use Data.init_cached()
instead of Data()
to initialize your object.
A more fancy approach would involve overriding Data.__new__()
to achieve the same thing, but where initialization with Data()
transparently checks if a cached version exists:
class Data(object):
def __new__(cls, filename):
if not os.path.exists(filename): # create new
return super(Data, cls).__new__(cls, filename, _save=True)
else:
with open(filename, 'rb') as fp:
return pickle.load(fp)
def __init__(self, filename, _save=False):
# [... expensive computations]
if _save:
self.save(filename)
Further reading: Python's use of __new__
and __init__
?
Upvotes: 2