Skip to content

Class Methods

Freedom

So far we always included the self- parameter into our methods, which is a placeholder for the object the method is called upon. Sometimes however we have the situation that we want to call a method on the class itself. In analogy to class attributes there are also class methods

Let us add a method that verifies if a given DNA sequence was could be output by the DnaSequencer:

from random import choices

class DnaSequencer:

    BASES = ["A", "C", "G", "T"]
    SEQUENCE_LENGTH = 2000

      # Methods as before

    @classmethod
    def verify_dna_sequence(cls, dna_sequence):
        if len(dna_sequence) != cls.SEQUENCE_LENGTH:
            return False  # Sequence is too long or short
        for base in dna_sequence:
            if base not in cls.BASES:
                return False  # Encountered a symbol in the sequence that doesn't belong there
        return True  # None of the previous checks failed, should be fine

Here we see a new thing, called an decorator. It wraps management code around a method (or function) so you don’t have to worry about it.

More on Decorators

Decorators in themselves are a very advanced concept. If you are curious, check out this primer on Python decorators In case you work(ed) with the Java programming language, don’t confuse decorators with Java annotations, they look similar but do different things

The @classmethod-decorator helps Python to distinguish that the following method is meant to be used in a specific way. If it were not there, Python would take verify_dna_sequence(…) as a (regular) instance method with a curious name for the self-parameter.

This way however it is clear that the method is supporsed to operate on the class itself. Similar to the self with the instance methods, the first parameter is special and gets replaced automatically by the class the method is called upon. It is named cls by convention.

Here is an example:

# Create some test sequences
valid_base = DnaSequencer.BASES[0]  # just picked the first one
valid_length = DnaSequencer.SEQUENCE_LENGTH

correct_sequence = valid_base * valid_length  # 2000 "A"s
short_sequence = valid_base * (valid_length - 1)  # only 1999 "A"s
wrong_sequence = "x" * valid_length  # 2000 "x"s

# Note how the method is called:
#  Based on the class name and without the implicit `cls` parameter
print(DnaSequencer.verify_dna_sequence(correct_sequence))  # True
print(DnaSequencer.verify_dna_sequence(short_sequence))  # False
print(DnaSequencer.verify_dna_sequence(wrong_sequence))  # False

Now try your hand at Task 7