2

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...

2 Answers 2

6

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..)

Sign up to request clarification or add additional context in comments.

3 Comments

What is this get_ business? Python has real properties.
I wouldn't call them real. They're just wrappers on methods. You may as well make a property class that sets up a property - having to define 'get' and 'set's after specifying that something is a property doesn't quite gel with me. When the OP has questions about properties, I'll keep an eye out, but this one seemed to be about OO and inheritance.
Excellent. So my intuition was correct: I need to set everything to None, and then set their values upon request. Thanks.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.