top of page
Writer's pictureVijithkumar V

Python @classmethod: Life Sciences Applications and Examples.

Updated: 4 days ago


Minion family. baby minion representing the classmethod is standing next to bigger minion representing the class instance. Another minion sitting and readign newspaper.
classmethods can be called on Class itself in addition to any Instance of the class.

Class methods are defined using the @classmethod decorator and enable calling a method directly on a class without requiring an instance of the class.

When you want to call a method directly on a class without requiring an instance of the class, you can convert the method into a class method using the @classmethod decorator."

Here, we have converted the method cls_method into a class method using the @classmethod decorator.

Therefore, we were able to call the method cls_method directly on the class ClassmethodEx1.

When a class method is called directly on a class, it receives the class as the first argument; consequently, when the code executes, the class is passed as an argument to the cls parameter of the class method cls_method.

That is why cls.cls_var returned the value of the class variable cls_var, and cls.name returned the name of the class ClassmethodEx1.


Now, let's see what happens if we call the class method on an instance instead of the class.


This also worked: it returned the class variable cls_var and printed the name of the class, ClassmethodEx1.

This means that even when you call the class method on an instance of the class, it still works because it passes the class as the first argument.

Now, let's create an instance method within this class.


It outputs as follows

Error: ClassmethodEx1.inst_method() missing 1 required positional argument: 'self' - inst_method was called without an instance of the class.


Here, the problem was that we called the instance method directly on the class ClassmethodEx1 without passing an instance of the class as an argument. Therefore, this will raise an error. There are two ways to solve this issue:

1. Create an instance of the class and call the instance method on that instance.

2. Call the instance method directly on the class and explicitly pass the instance as an argument.


This outputs as follows:

called from ClassmethodEx1

This is an instance method

Now we can call the instance method by calling the method on the class ClassmethodEx1 and pass the name of the instance.


This outputs as follows:

called from ClassmethodEx1

This is an instance method


 

A class variable can be accessed within both instance methods and class methods.

When the class variable is accessed within an instance method, it is accessed through the instance.

When you want to access the class variable within a class method, it is accessed through the class.

Let's look at an example.


This outputs as follows:

called from instance of ClassmethodEx1

The class variable is class_variable

called from class method of ClassmethodEx1

The class variable is class_variable


An instance variable can be accessed within a class method, but this requires the class method to have an instance parameter in addition to the cls parameter. When the class method is called on an instance, the instance must be passed as an argument.

Let's consider the example below.


This outputs as follows:

called from instance of ClassmethodEx1

The instance variable is: instance variable

called from class method of ClassmethodEx1


Even though this code works, it is not commonly recommended to access instance data from a class method. Generally, it is well-accepted to access instance data from a specific instance.


 

Now, let's look at an example.

Let's consider a DNA sequence and calculate the percentage of each nucleotide. In this example, the DNA sequence will be assigned to a class variable, while the nucleotide for which the percentage of occurrence needs to be calculated will be assigned to an instance variable.


This outputs as follows:

The percentage fraction of A: 22.95%


 

An important application of class methods is managing class-level data across various instances. Class-level data is managed within a class method.

Let's look at an example.

and

Let's write a program that calculates the area and perimeter of a circle. In this program, we will assign the class variable 'pi' a value of 3.14 and explain how this value can be changed across multiple instances.


This outputs as follows:

78.5

78.53750000000001


 

Class state refers to data shared across all instances of a class. This data is stored in class variables, which are defined outside of class instances. Class variables can be accessed and modified within both class methods and instance methods, although class methods are the conventional way to access and modify class state.

Let's look at an example.


This outputs as follows:

2

2

In this example code, we modify the class state within an instance method. Additionally, we include a class method that returns the class-level data.


 

Now, let's examine an example of modifying class-level data using a class method.


This outputs as follows:

2

2


 

Let's consider a real-world example. Below, we'll modify class-level data within a class method.

In this example, we'll pass short nucleotide sequences as arguments to the constructor method. The complementary sequence will be generated and appended to a class-level dictionary. Additionally, we'll define a class method to retrieve this dictionary.


This outputs as follows:

{'ATGCCGTAATCGGTACT': 'TACGGCATTAGCCATGA', 'AATCGGTACTATGCCGT': 'TTAGCCATGATACGGCA'}

{'ATGCCGTAATCGGTACT': 'TACGGCATTAGCCATGA', 'AATCGGTACTATGCCGT': 'TTAGCCATGATACGGCA'}

 

Let's see how we can modify the class data within the instance method.


This outputs as follows:

{'AATGCCGTAATCGGTACT': 'TTACGGCATTAGCCATGA'}

{'AATGCCGTAATCGGTACT': 'TTACGGCATTAGCCATGA'}


 

Now, let's explore some applications of class methods.

Apart from accessing and modifying class-level data, class methods can be used to create alternative constructors.

Typically, a class constructor requires distinct arguments. Class methods, however, enable you to create constructors from arguments in various formats.

and

For instance, consider a program that wishes someone a happy birthday, referencing their age. The primary constructor takes the person's name and current age.


This outputs as follows:

Hi John happy birthday! You have turned 30


You can make the code more flexible by letting the user enter the year of birth.


This outputs as follows:

Hi john happy birthday! You have turned 30

Hi john happy birthday! You have turned 30


Here, we can see that the class method returns the instance of the class and it automatically calls the class' constructor method with name and age, even though we called the classmethod with name and the year of birth(yob).

 

let's look at a real-life example.

Let's write a code that takes a DNA sequence and calculates the number of each nucleotide. We can either give a DNA sequence as a string or provide it as a file object.


This outputs as follows:

The sequence: ATGCCGTAATCGGTACT contains the following nucleotides

A: 4, T: 5, G: 4, C: 4

The sequence: CGGCGCGGGACAAGGTGACAGCGGCATGTGCAAAGCTGCGCCATAAGAAAAAGAAAGTGGCTTCTGGGAAAGCCACTATCTCTGAACTGAGGAGGAAGCTGGGACTAGCCGAGTCCCAGCAAGCTTCAATAAATGAGCAGGCGGCTT contains the following nucleotides

A: 44, T: 23, G: 47, C: 33


 

You can override a class method implemented by a parent class while still accessing the original method from the subclass. Let's examine an example where a subclass overrides a class method but accesses the parent's method using super()


This outputs as follows:

The sequence is a Nucleotide sequence

sequence: ATGCCGTAATCGGTACT

The sequence is a Protein sequence

sequence: ARNDEQGHILKMFPSTWYV


 

Let's consider an example that encompasses two key use cases:

  1. Utilizing a class method as an alternative constructor.

  2. Creating a subclass that overrides the class method to implement additional functionalities, while accessing the attributes and methods of the parent class




 

Another instance of application of @classmethod. The @classmethod can be used to generate an alternative constructor.

In this example, we will use classmethod to generate subclass-specific constructors.

The classmethod of the parent class returns instances of the subclass.

Subclass can override the methods implemented by the baseclass while still maintain access to the functionalities of the baseclass.

In the given example, a parent class would take a *.gff file as input, create necessary attributes, and generate appropriate instances of the subclass.

Subclass will be able to access the attributes and methods of the baseclass, and it can also have its own implementation to enhance the functionalities.

Here, I have provided a simplified typical *.gff file output by the gene prediction pipeline AUGUSTUS for demonstration purpose.




 

Let's explore another use case of a class method that serves as a blueprint for generating content-aware subclass instances.

Within the subclass, we override methods implemented by the base class while maintaining access to them.

In the following example, we utilize the base class's class method to create instances of either GlobularProtein or MembraneProtein.


Make sure that your pdb file and the corresponding fasta file have the same basename.


 

Behavior of the super() function

Now, finally, let's look at the behavior of super() built-in function and how it helps in the class inheritance scenarios. Also, how the behavior is influenced by regular methods and classmethods.

The super() function is a built-in Python function that provides access to methods implemented by a parent class. It returns a proxy object that facilitates method calls to the parent class (or the next immediate class in the Method Resolution Order, MRO).

Behavioral Variations

The behavior of super() varies depending on:

  1. Whether the method called is a class method, instance method, or static method

  2. The calling context of the method


Let's look at each scenario.

  1. super().method() within an Instance Method

When super().method() is called within an instance method, and the method is also an instance method:

  1. super() detects the method implemented by the parent class and binds it to the instance of the subclass

  2. This is the default behavior of super()

  3. The "self" parameter of the method receives the instance of the subclass.



This outputs as follows:

Calling Inherited Parent Method

Accessed Inherited Parent Mathod

Called Inherited Parent Method Within the Child Class


Now, let's see what the self refers to that was bound to the method.


This outputs as follows:

Calling Inherited Parent Method

Accessed Inherited Parent Mathod

The self refers to the instance of Child

Called Inherited Parent Method Within the Child Class


 

2. super().method() implemented within an instance method the inherited method that is being accessed is a classmethod.

Let's look at an example


Now let's see what the cls refers to here.


The output is as follows:

Calling Inherited Parent Method

Accessed Inherited Parent Mathod

The self refers to Child

Called Inherited Parent Method Within the Child Class.


 

3. super().method() was implemented within a classmethod where the inherted method that is being accessed is also a classmethod.

Let's look at an example.


The output is as follows:

Calling Inherited Parent Method

Accessed Inherited Parent Mathod

Called Inherited Parent Method Within the Child Class


Now, let's see if it was the class itself that was passed to the cls parameter of the inherited method


The output is as follows:

Calling Inherited Parent Method

Accessed Inherited Parent Mathod

The cls refers to Child

Called Inherited Parent Method Within the Child Class


 

4. Now, let's see the scenario where the super().method() is implemented within a classmethod and the

inherited method being accessed is an instance method.


The output is as follows. It throws back a TypeError

Traceback (most recent call last):

File "c:\Users\USER\OneDrive\Desktop\tempCodeRunnerFile.py", line 15, in <module>

Calling Inherited Parent Method

child.method()

File "c:\Users\USER\OneDrive\Desktop\tempCodeRunnerFile.py", line 11, in method

super().method()

TypeError: Parent.method() missing 1 required positional argument: 'self'



 

Understanding super() Behavior.

When super().method() is called without arguments within a child/subclass method, it assumes two arguments:

  1. type: The enclosing class where super() is called.

  2. object_or_type: The first argument passed to the method.

Explicit and Implicit Forms of super()

  1. Explicit: super(type, object_or_type)

  2. Implicit: super() (only usable within a class definition)

Return Value and Method Resolution

super() returns a proxy object that delegates method calls to the parent or sibling class of type. The proxy object:

  1. Searches classes in a predictable order (Method Resolution Order, MRO) determined by obj_or_Type.__mro__.

  2. Calls the method with obj_or_Type if found in the next immediate class (parent or sibling).

MRO Example

For Child class, MRO is:

Child -> Parent -> Object

Error Explanation

When calling method (implemented as a regular method within Parent) using super().method() within the classmethod of Child, an error occurs because:

  1. super() expects an instance as the second argument, but receives the class instead.

  2. method is bound to the class, not an instance.

The error was:

Traceback (most recent call last):

File "c:\Users\USER\OneDrive\Desktop\tempCodeRunnerFile.py", line 15, in <module>

Calling Inherited Parent Method

child.method()

File "c:\Users\USER\OneDrive\Desktop\tempCodeRunnerFile.py", line 11, in method

super().method()

TypeError: Parent.method() missing 1 required positional argument: 'self'


Here, the Parent.method() is a regular method and expects an instance of the Type. The parent method can be called using Parent.method(self). Since super().method() was called within a classmethod, the issubclass(obj_or_type, type) is True, and the method is called with the class itself.



123 views0 comments

コメント


bottom of page