Python Class Variables vs. Instance Variables: Differences and How to Update Correctly (Beware of Shadowing)

In Python classes, there are two main types of variables: “Class Variables” and “Instance Variables.” These differ fundamentally in where they are defined, their scope, and how data is held.

A common trap for Python beginners is the behavior when “trying to rewrite a class variable from an instance.” This article explains the basic usage of class variables, how they differ from instance variables, and the correct way to update them to prevent unintended bugs.


目次

Differences Between Class Variables and Instance Variables

Class Variables

  • Definition Location: Directly under the class block (outside of methods).
  • Characteristics: A value shared by all instances generated from that class.
  • Usage: Constants, default settings, counting the total number of instances, etc.

Instance Variables

  • Definition Location: Inside methods like __init__, defined as self.variable_name.
  • Characteristics: A value independent for each individual instance.
  • Usage: Name, age, individual status, etc.

Specific Code Example: User Management Class

As an example, let’s create a class representing a user of a web service. We manage the site name (common to all) as a “Class Variable” and the user name (individual) as an “Instance Variable,” while also counting the total number of users.

class SiteUser:
    """
    User Management Class
    """
    # --- Class Variables ---
    # Shared by all instances
    site_name = "Python Study Portal"
    total_user_count = 0

    def __init__(self, username):
        """Constructor"""
        # --- Instance Variables ---
        # Independent for each instance
        self.username = username
        
        # Update (increment) the class variable when an instance is created
        SiteUser.total_user_count += 1

    def show_info(self):
        print(f"Site: {SiteUser.site_name} | User: {self.username}")

# 1. Class variables can be referenced without instantiation
print(f"Initial User Count: {SiteUser.total_user_count}")

# 2. Create instances
user1 = SiteUser("Tanaka")
user2 = SiteUser("Suzuki")

# 3. Display info for each instance
user1.show_info()
user2.show_info()

# 4. Confirm that the class variable is shared
# The value of the class variable is the same from any instance's perspective
print(f"Count seen from user1: {user1.total_user_count}")
print(f"Count seen from user2: {user2.total_user_count}")
print(f"Count seen from Class: {SiteUser.total_user_count}")

Output:

Initial User Count: 0
Site: Python Study Portal | User: Tanaka
Site: Python Study Portal | User: Suzuki
Count seen from user1: 2
Count seen from user2: 2
Count seen from Class: 2

You can see that by creating user1 and user2, the shared total_user_count has increased to 2.


Important Note: Assignment via Instance (Shadowing)

The most important thing to watch out for when handling class variables is: “Do not assign values to class variables via an instance.”

If you perform an assignment like user1.site_name = "New Site", the class variable is not updated. Instead, a new instance variable with the same name is created inside the user1 instance. This is called variable “Shadowing”.

# Current value of class variable
print(f"[Before] Class: {SiteUser.site_name}, user1: {user1.site_name}, user2: {user2.site_name}")

# [BAD EXAMPLE] Assigning via instance
# Intending to change the class variable, but...
user1.site_name = "Renamed Portal"

# Verification
print(f"[After]  Class: {SiteUser.site_name}, user1: {user1.site_name}, user2: {user2.site_name}")

Output:

[Before] Class: Python Study Portal, user1: Python Study Portal, user2: Python Study Portal
[After]  Class: Python Study Portal, user1: Renamed Portal, user2: Python Study Portal

Explanation:

  1. user1.site_name: Changed to “Renamed Portal”. This is a newly created instance variable inside user1.
  2. SiteUser.site_name: Remains as before. The class variable was not updated.
  3. user2.site_name: Remains as before. It continues to reference the class variable.

This causes a bug where only user1 falls out of sync with the shared data.


Correct Update Method

If you want to update a class variable, you must access it using the Class Name.

# [GOOD EXAMPLE] Assigning using the Class Name
SiteUser.site_name = "Official Python Site"

# Reflected in all
print(f"Class: {SiteUser.site_name}")
print(f"user2: {user2.site_name}")

# (Note: user1 still displays its own instance variable created in the previous step)

Summary

  • Class Variable: Accessed via ClassName.var. Used for data shared by all instances.
  • Instance Variable: Accessed via self.var. Used for individual data.
  • Update Rule: When updating a class variable, always write ClassName.var = value.
    • Writing self.var = value or instance.var = value will create a new instance variable and shadow the class variable.
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次