Comprehensive Guide to Python Classes: From Instance Variables to Inter-Class Interactions

Nov 23, 2025 · Programming · 9 views · 7.8

Keywords: Python classes | instance variables | self parameter | class instantiation | method invocation | namespaces

Abstract: This article provides an in-depth exploration of Python's class mechanisms, covering instance variable scoping, the nature of the self parameter, parameter passing during class instantiation, and cross-class method invocation. By refactoring code examples from the Q&A, it systematically explains the differences between class and instance variables, the execution timing of __init__, the underlying principles of method binding, and variable lookup priorities based on namespace theory. The article also analyzes correct practices for creating instances between classes to avoid common variable passing errors, offering a solid theoretical foundation and practical guidance for object-oriented programming.

Basic Class Structure and Instance Variable Scope

In Python, classes initialize instance attributes via the __init__ method. Variables defined with self.variable = value are instance variables, whose scope covers all methods of the class. For example:

class ExampleClass:
    def __init__(self):
        self.instance_var = "initial value"
    
    def method1(self):
        # Can access and modify instance variables
        self.instance_var = "modified value"
        print(self.instance_var)
    
    def method2(self):
        # Also can access instance variables
        print(self.instance_var)

Here, self.instance_var is accessible in both method1 and method2, and modifications in method1 affect the output in method2. Instance variables act like "global variables for each instance" but are confined to that instance.

Nature and Usage of the self Parameter

self is the first parameter of class methods, representing the current instance object. Python automatically passes the instance reference when calling a method, so methods must use self to access instance attributes and other methods. For example:

class DemoClass:
    def __init__(self, value):
        self.data = value
    
    def show_data(self):
        print(f"Data value: {self.data}")
    
    def process_data(self):
        # Must use self to call other methods
        self.show_data()
        self.data += 10

Omitting self, such as writing show_data() directly, will cause a Python error due to unbound instance. While self is a convention and can be replaced with other identifiers, it violates coding standards.

Class Instantiation and Parameter Passing

When creating a class instance, parameters are passed through the __init__ method. Calling the class name with arguments automatically invokes __init__ and initializes the instance. For example:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def introduce(self):
        print(f"I am {self.name}, {self.age} years old")

# Instantiate and pass parameters
person1 = Person("John", 30)
person1.introduce()  # Output: I am John, 30 years old

Parameters name and age are passed during instantiation and bound to instance attributes. If __init__ has no parameters, no values need to be passed during instantiation.

Method Invocation Outside the Class

Class methods are called via instance objects, in the format instance.method(). Python automatically passes the instance as the self parameter. For example:

class Calculator:
    def __init__(self):
        self.result = 0
    
    def add(self, x, y):
        self.result = x + y
        return self.result

calc = Calculator()
sum_value = calc.add(5, 3)  # Correct call, output: 8
print(sum_value)

Directly calling Calculator.add(5, 3) will error because the self parameter is missing. Explicitly passing the instance allows equivalent calls: Calculator.add(calc, 5, 3), but this is not recommended.

Instance Creation Between Classes and Variable Passing

When creating an instance of another class within a class, ensure variables are passed correctly. Refactored example based on the Q&A code:

class OtherClass:
    def __init__(self, var1, var2, var3):
        self.var1 = var1
        self.var2 = var2
        self.var3 = var3
    
    def process_data(self):
        # Use instance variables for computation
        temp = len(self.var3)  # Example operation
        self.var2.append(temp)
        print(self.var2)

class InitialClass:
    def __init__(self):
        self.var1 = "default"
        self.var2 = []
        self.var3 = "example"
        # Create OtherClass instance, passing current instance's variables
        self.other_instance = OtherClass(self.var1, self.var2, self.var3)
    
    def execute_process(self):
        # Call OtherClass's method
        self.other_instance.process_data()

# Usage example
init_obj = InitialClass()
init_obj.execute_process()  # Output based on operations with var2 and var3

The key is passing the current instance's variable values via self.var1 etc., ensuring the OtherClass instance receives correct data. Avoid using unbound variable names like variable1 without self as in the original code.

Differences Between Class and Instance Variables

Class variables are shared among all instances, while instance variables are independent per instance. For example:

class SharedExample:
    class_var = "shared value"  # Class variable
    
    def __init__(self, inst_val):
        self.inst_var = inst_val  # Instance variable

obj1 = SharedExample("instance1")
obj2 = SharedExample("instance2")

print(obj1.class_var)  # Output: shared value
print(obj2.class_var)  # Output: shared value

# Modifying class variable affects all instances
SharedExample.class_var = "new shared value"
print(obj1.class_var)  # Output: new shared value

# Instance variables do not affect each other
obj1.inst_var = "modified instance1"
print(obj2.inst_var)   # Output: instance2

If an instance attribute has the same name as a class attribute, instance access prioritizes the instance attribute. Modifying a class variable via the class name affects all instances, while modifying via an instance creates a new instance attribute.

Namespaces and Variable Lookup Mechanism

Python uses namespaces to manage variables, with class definitions creating new namespaces. During instantiation, instances have independent namespaces for instance variables. Variable lookup in methods follows: local namespace → instance namespace → class namespace → global namespace → built-in namespace. For example:

class NamespaceDemo:
    class_attr = "class attribute"
    
    def __init__(self):
        self.inst_attr = "instance attribute"
    
    def check_scope(self):
        local_var = "local variable"
        print(local_var)        # Local namespace
        print(self.inst_attr)   # Instance namespace
        print(self.class_attr)  # Class namespace (via instance)
        print(NamespaceDemo.class_attr)  # Class namespace (direct access)

Understanding namespaces helps avoid variable shadowing errors and ensures code references the intended variables correctly.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.