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
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
@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
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 # 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