Fundamentals 5 min read

Understanding Static, Class, and Instance Methods in Python

This article explains Python's static, class, and instance methods, detailing their definitions, usage with @staticmethod and @classmethod decorators, code examples, expected outputs, and common pitfalls such as TypeError when calling non‑static methods via instances.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Understanding Static, Class, and Instance Methods in Python

Static methods are ordinary functions defined inside a class that do not operate on class or instance data; they are declared with the @staticmethod decorator. They are useful for grouping logically related functions under a class namespace.

Example:

import time
class TimeTest():
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second

    @staticmethod
    def show_time():
        return time.strftime('%H:%m:%s', time.localtime())

if __name__ == '__main__':
    # Both calls are valid
    print(TimeTest.show_time())
    print(TimeTest(1, 0, 0).show_time())

Running the code prints the current time twice, e.g., 20:04:1555158168 .

If a method lacks the @staticmethod decorator but is called on an instance, Python passes the instance as the first argument, causing a TypeError because the method expects no parameters.

class Animal(object):
    # @staticmethod
    def greet():
        pass

if __name__ == '__main__':
    # This call raises an error
    Animal().greet()

The error message is:

TypeError: greet() takes 0 positional arguments but 1 was given

Class methods are declared with @classmethod and receive the class itself as the first argument (conventionally named cls ). They can be called via the class or an instance, and cls always refers to the class that invoked the method.

class Persion(object):
    @classmethod
    def treasure(cls):
        print(__name__, type(cls), cls, sep='||')

if __name__ == '__main__':
    # Both class and instance calls work
    Persion.treasure()
    Persion().treasure()

Output (shown twice):

__main__||<class 'type'>||<class '__main__.Persion'>
__main__||<class 'type'>||<class '__main__.Persion'>

When inheritance is involved, the class method receives the subclass that invoked it, not the superclass where it was defined.

class Someone(Persion):
    pass

if __name__ == '__main__':
    Someone.treasure()
    Someone().treasure()

Output demonstrates that cls is Someone :

&lt;class '__main__.Someone'&gt;
&lt;class 'type'&gt; &lt;class '__main__.Someone'&gt;

Instance methods require the first parameter to be the instance itself (conventionally self ). The instance is passed automatically when called on an object, but if the method is invoked on the class, the instance must be supplied explicitly.

class Test(object):
    def __init__(self, name):
        self.name = name
    def get_gender(self, gender):
        return ('{} is a {}').format(self.name, gender)

if __name__ == '__main__':
    alex = Test('Alex')
    anna = Test('Anna')
    # Both calls are valid
    print(alex.get_gender('boy'))
    print(Test.get_gender(anna, 'girl'))

Running the code prints:

Alex is a boy
Anna is a girl
PythonOOPcodingclass methodinstance methodstatic method
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.