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