Reputation: 18166
OO isn't my strongest suit, so please bear with me. I want to design a class structure something like this:
class Mammal(object):
def __init__(self):
super(Mammal, self).__init__()
self.dna_sequence = self.sequence_dna()
def sequence_dna(self):
blood_sample = 42
# Code goes here to sequence the mammal's DNA - may take a while.
Then, over in another class, I want to inherit from Mammal:
class Human(Mammal):
super(Human, self).__init__()
self.dna_sequence = self.sequence_dna()
def sequence_dna(self):
blood_sample = 43
# use blood sample and Human algo to sequence it.
So here's where I'm stuck. When I create the Human object, I don't want it to go and do the DNA sequencing, cause that takes a while. But I need the Human object to have the dna_sequence attribute so that I can do the sequencing later. Is the solution, to set the attribute in the init method, but to set it to None
until the sequence_dna method is called? Seems kludgy, especially since I have many variables, all of which will depend on the outcome of the DNA sequencing and thus be set to None.
I feel like I'm missing a piece of the puzzle...
Upvotes: 2
Views: 1201
Reputation: 28036
One way to handle this is lazy initialization. You could do something like..
class Mammal(object):
def __init__(self):
self.blood_sample = 42
self.dna_sequence = None
def get_dna_sequence(self):
if self.dna_sequence == None:
self.generate_dna_sequence(self.blood_sample)
return self.dna_sequence
def generate_dna_sequence(self, blood_sample=None):
self.dna_sequence = stuff_to_generate_sequence(blood_sample)
class Human(Mammal):
def __init__(self):
super(Mammal, self).__init__()
self.blood_sample = 43
Then, human automatically inherits 'get_dna_sequence', but both versions only go through the process of calculating it on request.
You can further pimp up the get_dna_sequence() method by making it a generator, on the off-chance that the computation/mapping you're doing can be 'chunked', you should yield out chunks of it as it's being processed so that you don't have to hold the entire thing in memory. (Which, for DNA I think would be pretty big..)
Upvotes: 6
Reputation: 49826
There is no reason why you can't initialise the variable to None
.
Probably the piece of the puzzle that is missing is that the variable should not be the primary interface for users of your class to get the gene sequence value. Have them call the sequence method, and if the sequence method is expensive, just use the member variable as a cache for the result.
Upvotes: 1