Python Static Class Data and Methods

First, let’s take a look at what static class data is all about. Imagine you have a class called `Person` that needs to store some basic information like name and age:

# This is a class called Person that stores basic information like name and age
class Person:
    # This is a static class data that is shared by all instances of the class
    species = "Homo sapiens"
    
    # This is the constructor method that initializes the object with name and age
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    # This is a method that prints out an introduction using the object's name and age
    def introduce(self):
        print("Hi, my name is {} and I'm {} years old.".format(self.name, self.age))

In this example, weve added a new variable called `species` to the class itself (outside of any method or constructor). This means that it will be available for all instances of the `Person` class without having to create an object first:

# Adding a new variable called `species` to the class itself
class Person:
    # `species` variable is declared outside of any method or constructor
    species = "Homo sapiens"

    # `__init__` method is used to initialize the object with `name` and `age` attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # `greet` method is used to print a greeting message with the person's name
    def greet(self):
        print("Hello, my name is " + self.name)

# Creating an instance of the `Person` class
person1 = Person("John", 25)

# Accessing the `species` variable from the class itself
print(Person.species) # prints "Homo sapiens"

# Accessing the `species` variable from an instance of the `Person` class
print(person1.species) # prints "Homo sapiens"

# Calling the `greet` method from the instance of the `Person` class
person1.greet() # prints "Hello, my name is John"

This is great if you have some information that doesnt change from instance to instance, like a species or currency symbol. It also helps keep your code cleaner and more organized by keeping all related data in one place.
Now static class methods these are functions defined within the class itself but dont require an object instance to be called. This can be useful for situations where you want to perform some operation without having to create a new object or if you have functionality that doesnt depend on any specific data from an object:

# This is a class called Person
class Person:
    # This is a static class data that is shared by all instances of the class
    species = "Homo sapiens" 
    
    # This is a constructor method that initializes the object with a name and age
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    # This is a static method that can be called without creating an object instance
    # It checks if the person is an adult by comparing their age to 18
    @staticmethod
    def is_adult(person):
        return person.age >= 18

In this example, weve added a new function called `is_adult()`. This function takes an object as input (in this case, another instance of the `Person` class) but doesnt require it to be called on that specific object:

# Define the Person class
class Person:
    # Initialize the class with name and age attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # Define the is_adult function
    def is_adult(self, other_person):
        # Check if the age of the other person is greater than or equal to 18
        if other_person.age >= 18:
            # If yes, return True
            return True
        else:
            # If no, return False
            return False

# Create an instance of the Person class with name "John Doe" and age 25
person = Person("John Doe", 25)

# Call the is_adult function on the Person class, passing in the person instance as an argument
is_adult = person.is_adult(person)

# Print the result of the is_adult function
print(is_adult) # prints True

This can be incredibly useful for situations where you want to perform some operation without having to create a new instance of the class or if you have functionality that doesnt depend on any specific data from an object.
This is just scratching the surface, but hopefully this tutorial has given you a good understanding of what they are and how to use them.

SICORPS