PythonObject Oriented Programming

Python Class Methods and Attributes: Complete Guide

TT
TopicTrick
Python Class Methods and Attributes: Complete Guide

What are Python Class Members?

Python class members are the variables (attributes) and functions (methods) that belong to a class. Choosing the right type — instance, class, or static — is the key to writing clean, efficient OOP code that scales.

Introduction to Class Members

In our previous tutorial, we covered the basics of Python OOP. Now, let's explore the "members" of a class—the variables and methods that give your objects data and functionality.

Typically, a Python class consists of:

  • Docstrings: For documentation.
  • Built-in Attributes: Predefined metadata.
  • Variables: To store state (Instance, Class, Private).
  • Methods: To define behavior (Instance, Class, Static, Magic).

1. Docstrings & Built-in Attributes

Docstrings

A docstring is a string literal used to describe the purpose of your class or method. It’s accessed via the __doc__ attribute.

python

Essential Built-in Attributes

Every Python class comes with several built-in attributes that provide metadata:

AttributeDescription
__name__Returns the name of the class.
__module__Returns the name of the module where the class is defined.
__bases__Returns a tuple of base classes (parent classes).
__dict__Returns a dictionary containing the class's namespace.

2. Types of Variables

Instance Variables

These are unique to each object. Every instance has its own copy, and changing one doesn't affect the others. They are usually defined inside the __init__ constructor.

python

Class Variables

These are shared by ALL instances of a class. They are defined outside the constructor.

python

Avoid Altering Class Variables via Instances

If you do `instance.classvariable = newvalue`, Python creates a NEW instance variable for that specific object instead of changing the class-wide value. Always use `ClassName.variablename` to update class variables.

    Private Variables (Name Mangling)

    Python doesn't have true "private" variables, but it uses a convention called Name Mangling. Any attribute starting with __ (double underscore) is "hidden."

    python

    3. Types of Methods

    Instance Methods

    The most common type. They take self as the first argument and can access/modify instance-specific data.

    python

    Class Methods

    Bound to the class itself, not the instance. They take cls as the first argument and are marked with the @classmethod decorator. Use them for factory methods or modifying class state.

    python

    Static Methods

    These don't take self or cls. They act like regular functions but are grouped within the class for organization (Utility functions).

    python

    Magic (Dunder) Methods

    These have double underscores (e.g., __init__, __str__). They allow you to perform special operations like operator overloading.


    4. Practical Example: Combining All Member Types

    Here is a complete example that shows all three method types and all three variable types working together in a real-world Employee class:

    python

    When to Use Each Method Type

    Method TypeUse When...Example
    Instance MethodYou need to access or modify self dataget_salary(), deposit()
    Class MethodYou need a factory or to read class-level statefrom_string(), get_count()
    Static MethodYou have a utility function related to the class but not dependent on itis_valid_email(), validate_id()

    Related Python OOP Topics

    For the official reference, see the Python Classes documentation, the section on classmethod and staticmethod, and the Python data model: special method names.

    Common Mistakes with Class Members

    1. Modifying a class variable through an instance. Writing instance.class_var = value does not update the class-wide value — it creates a new instance variable that shadows it. Always use ClassName.class_var = value to update shared state.

    2. Putting mutable defaults in class variables. If a class variable is a list or dict, all instances share that same object. Appending to it in one instance affects all others. Define mutable attributes in __init__ instead.

    3. Overusing static methods. If a static method grows to need class or instance data, converting it to an instance or class method becomes awkward. When in doubt, start with an instance method.

    4. Using double underscores (__) for every private attribute. Name mangling (__attr becomes _ClassName__attr) is intended to prevent accidental overriding in subclasses, not as a general privacy mechanism. Use a single underscore _attr for most "internal" attributes.

    5. Confusing @classmethod with @staticmethod. Class methods receive cls as their first argument and can access class state. Static methods receive neither self nor cls — they are plain functions scoped to the class namespace for organisation purposes.

    Best Practices

    1. Use @classmethod as factory methods to provide alternative constructors (from_string, from_dict).
    2. Use @staticmethod for pure utility functions that logically belong in the class but don't need access to self or cls.
    3. Expose private data via properties (@property) rather than a plain getter method — it reads more naturally (obj.salary vs obj.get_salary()).
    4. Keep class variables for genuinely shared, read-only data (constants, registry entries) and instance variables for anything that differs per object.
    5. Document the distinction between class and instance variables with a class-level docstring so maintainers understand the intent.
    6. Always call super().__init__() in subclass constructors to avoid breaking parent class initialization.

    FAQ

    What is the difference between a class method and a static method?

    A class method receives cls as its first argument, giving it access to and the ability to modify class-level state. A static method receives no implicit first argument and behaves like a regular function that is namespaced inside the class for organisation. Use a class method when you need to access or change the class; use a static method when you just want to group a utility function with the class.

    Can you call a class method on an instance?

    Yes. instance.my_classmethod() works — Python passes the class (not the instance) as cls. However, calling it on the class directly (MyClass.my_classmethod()) is clearer and conventional.

    What is name mangling in Python?

    When an attribute name starts with two underscores (__attr), Python internally renames it to _ClassName__attr. This prevents accidental overriding in subclasses but does not provide true access control — the mangled name is still accessible from outside the class if you know it.

    Conclusion

    Understanding the difference between these members is key to writing clean, efficient OOP code. You now know how to manage shared data with Class Variables, protect data with Private Variables, and organize logic with Static Methods.

    What's Next?

    Up next, we'll explore Inheritance and how to reuse code across multiple classes!

      Common Mistakes with Python Classes

      1. Mutable default class attributes

      python

      Every instance shares the same list. Define mutable attributes in __init__ instead: self.members = []. See the Python class documentation.

      2. Confusing @classmethod and @staticmethod @classmethod receives the class as its first argument (cls) and can access or modify class state. @staticmethod receives no implicit first argument and is essentially a plain function namespaced inside the class. Use @classmethod for alternative constructors and factory methods.

      3. Forgetting self in instance methods Every instance method must have self as its first parameter. Omitting it causes TypeError: takes 0 positional arguments but 1 was given — Python automatically passes the instance as the first argument.

      4. Using __class__ instead of type(self) Inside a method, self.__class__ and type(self) are usually equivalent, but type(self) is more explicit and works correctly with metaclasses and __class__ cell optimisations.

      5. Not using super() in __init__ When subclassing, forgetting super().__init__() means the parent class is never initialised. Always call super().__init__(*args, **kwargs) in the child's __init__ unless you deliberately want to skip parent initialisation.

      Frequently Asked Questions

      What is the difference between a class attribute and an instance attribute? A class attribute is defined at class level and shared across all instances. An instance attribute is defined inside __init__ (or other methods) with self.attr = value and belongs to a specific instance. Instance attributes shadow class attributes of the same name. The Python data model documentation covers the attribute lookup chain.

      When should I use @property instead of a regular attribute? Use @property when you need to compute a value on access, validate a value on assignment, or maintain backward compatibility when changing a public attribute to computed logic. It provides getter/setter semantics with clean dot-notation access.

      What is __slots__ and when should I use it? __slots__ replaces the per-instance __dict__ with a fixed set of attributes, reducing memory usage significantly for classes with many instances. Use it for data-heavy classes (e.g. holding millions of records) where memory is a concern. The trade-off is that you cannot add arbitrary attributes at runtime.