Python - Class Attributes

Hello, aspiring programmers! Today, we're going to dive into the exciting world of Python class attributes. Don't worry if you're new to programming; I'll guide you through this journey step by step, just like I've done for countless students over my years of teaching. So, let's get started!

Python - Class Attributes

Class Attributes (Variables)

Class attributes are variables that belong to the entire class rather than a specific instance of the class. Think of them as characteristics shared by all objects of that class.

Let's start with a simple example:

class Dog:
    species = "Canis familiaris"

    def __init__(self, name, age):
        self.name = name
        self.age = age

fluffy = Dog("Fluffy", 3)
buddy = Dog("Buddy", 5)

print(Dog.species)  # Output: Canis familiaris
print(fluffy.species)  # Output: Canis familiaris
print(buddy.species)  # Output: Canis familiaris

In this example, species is a class attribute. It's defined directly inside the class, but outside of any methods. All Dog objects share this attribute.

Accessing Class Attributes

As you can see from the example above, you can access class attributes in two ways:

  1. Through the class itself: Dog.species
  2. Through any instance of the class: fluffy.species or buddy.species

Both ways will give you the same result. It's like asking, "What species are dogs?" or "What species is Fluffy?" - the answer is the same!

Modifying Class Attributes

Class attributes can be modified, but be careful! When you modify a class attribute, it changes for all instances of the class. Let's see an example:

class Cat:
    species = "Felis catus"
    count = 0

    def __init__(self, name):
        self.name = name
        Cat.count += 1

whiskers = Cat("Whiskers")
mittens = Cat("Mittens")

print(Cat.count)  # Output: 2
print(whiskers.count)  # Output: 2
print(mittens.count)  # Output: 2

Cat.species = "Felis silvestris catus"

print(Cat.species)  # Output: Felis silvestris catus
print(whiskers.species)  # Output: Felis silvestris catus
print(mittens.species)  # Output: Felis silvestris catus

In this example, we're using a class attribute count to keep track of how many cats we've created. Each time we create a new Cat object, we increment Cat.count. We also changed the species for all cats at once by modifying Cat.species.

Significance of Class Attributes

Class attributes are incredibly useful in several scenarios:

  1. Storing constants that should be the same for all instances of a class.
  2. Keeping track of data across all instances of a class (like our Cat.count example).
  3. Defining default values that can be overridden in instances if needed.

Built-In Class Attributes

Python classes come with some built-in attributes that can be very helpful. Let's look at a few:

class MyClass:
    x = 5

    def my_method(self):
        pass

print(MyClass.__name__)  # Output: MyClass
print(MyClass.__doc__)  # Output: None (because we didn't provide a docstring)
print(MyClass.__dict__)  # Output: {'__module__': '__main__', 'x': 5, 'my_method': <function MyClass.my_method at ...>}
print(MyClass.__module__)  # Output: __main__

Access Built-In Class Attributes

Here's a table of some common built-in class attributes and how to access them:

Attribute Description Access
name Name of the class MyClass.name
doc Docstring of the class MyClass.doc
dict Dictionary containing the class's namespace MyClass.dict
module Name of the module in which the class is defined MyClass.module
bases Tuple containing the base classes MyClass.bases

Instance Attributes

Now that we understand class attributes, let's briefly touch on instance attributes to see the difference. Instance attributes are specific to each object created from the class.

class Student:
    school = "Python High"  # Class attribute

    def __init__(self, name, grade):
        self.name = name  # Instance attribute
        self.grade = grade  # Instance attribute

alice = Student("Alice", 10)
bob = Student("Bob", 11)

print(Student.school)  # Output: Python High
print(alice.school)    # Output: Python High
print(bob.school)      # Output: Python High

print(alice.name)      # Output: Alice
print(bob.name)        # Output: Bob

Student.school = "Python University"
print(alice.school)    # Output: Python University
print(bob.school)      # Output: Python University

alice.school = "Python Elementary"
print(alice.school)    # Output: Python Elementary
print(Student.school)  # Output: Python University
print(bob.school)      # Output: Python University

Instance Attributes Vs Class Attributes

The main differences between instance and class attributes are:

  1. Class attributes are shared by all instances, while instance attributes are unique to each instance.
  2. Class attributes are defined in the class but outside any methods, while instance attributes are typically defined inside the __init__ method.
  3. Changing a class attribute affects all instances (unless an instance has overridden it), while changing an instance attribute only affects that specific instance.

Remember, when you try to access an attribute on an instance, Python first looks for an instance attribute. If it doesn't find one, it then looks for a class attribute. This is why we can "override" a class attribute for a specific instance by creating an instance attribute with the same name.

And there you have it! You've just completed a crash course in Python class attributes. Remember, the key to mastering programming is practice. So don't be afraid to experiment with these concepts. Create your own classes, play around with attributes, and see what happens. Happy coding!

Credits: Image by storyset