Master Python Class vs Static Methods, Deep/Shallow Copies, and Decorators
This comprehensive guide explains Python’s class and static methods, compares deep and shallow copying techniques, demystifies decorators, and reveals how variables are stored in memory, providing clear examples and best‑practice recommendations for writing efficient, maintainable code.
Python Class Methods vs Static Methods
Class methods are defined with the
@classmethoddecorator and receive the class itself as the first argument
cls. They can access and modify class state, cannot access instance state, and are often used to define alternative constructors.
Example
<code>class MyClass:
class_variable = 0
@classmethod
def increment_class_variable(cls):
cls.class_variable += 1
@classmethod
def from_string(cls, string_param):
# alternative constructor
return cls(int(string_param))
MyClass.increment_class_variable()
obj = MyClass.from_string("10")
</code>Static Methods
Static methods are defined with the
@staticmethoddecorator and do not receive any special first argument. They cannot access or modify class or instance state and are used to group related functionality within a class.
Example
<code>class MathOperations:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def multiply(x, y):
return x * y
result = MathOperations.add(5, 3)
</code>Main Differences
Parameters : Class methods receive
cls, static methods receive none.
Access to class attributes : Class methods can read/modify them; static methods cannot.
Use cases : Class methods for operations needing class state or alternative constructors; static methods for utility functions related to the class.
Inheritance : In subclasses,
clsrefers to the subclass; static methods behave the same.
Choosing Between Them
If the method needs to access or modify class attributes, use a class method.
If the method only provides related functionality without touching class or instance state, use a static method.
Deep Copy vs Shallow Copy in Python
Shallow copy creates a new container object but inserts references to the original elements; it copies only the first level. It can be performed with slicing
[:], the
copy()method, or the
copymodule’s
copy()function.
Shallow Copy Example
<code>import copy
original = [1, [2, 3], 4]
shallow = copy.copy(original)
shallow[1][0] = 'X'
print(original) # [1, ['X', 3], 4]
print(shallow) # [1, ['X', 3], 4]
</code>Modifying a nested element in the shallow copy also changes the original.
Deep copy creates a completely independent object by recursively copying all nested objects, using
copy.deepcopy().
Deep Copy Example
<code>import copy
original = [1, [2, 3], 4]
deep = copy.deepcopy(original)
deep[1][0] = 'X'
print(original) # [1, [2, 3], 4]
print(deep) # [1, ['X', 3], 4]
</code>Changes in the deep copy do not affect the original. Deep copy uses more memory and is slower but guarantees full independence.
Python Variable Storage in Memory
Variables are references to objects. When a variable is assigned, it points to an object’s memory address. Objects contain a type identifier, reference count, and value.
Small integers (-5 to 256) and some strings are cached, so multiple variables may reference the same object. Larger integers and mutable objects like lists are allocated separately.
Reference Counting and Garbage Collection
Python tracks how many references point to an object; when the count drops to zero, the object is reclaimed.
<code>x = 5
y = x # reference count becomes 2
del x # count back to 1, y still holds the object
</code>Immutable objects create new instances when modified, while mutable objects can be changed in place without altering their identity.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.