Python Method Naming Conventions: Best Practices for Class Design

Some thoughts on naming instance, class, static, helper, and dunder methods in Python, with best practices and examples.
Python
Object-Oriented Programming
Best Practices
Published

February 4, 2025

Python Method Naming Conventions

Python Method Naming Conventions: Class Design

Naming methods in Python classes correctly improves readability, maintainability, and clarity. This post explores best practices for naming instance methods, class methods, static methods, helper methods, and dunder methods in Python.

1. Instance Methods (self)

Purpose: Operate on an instance of the class, modifying attributes or performing actions specific to an object.

  • Naming: Use snake_case (e.g., train_model, predict).

  • Example:

    class Model:
        def train(self, data):  # Instance method
            pass

Using _underscore in Instance Methods

  • _private_method(): A single underscore signals an internal (protected) method, not meant for public use.

    class Model:
        def _preprocess(self, data):  # Internal method
            pass
  • __double_underscore_method(): A double underscore triggers name-mangling, making it harder to override in subclasses.

    class Model:
        def __compute_loss(self, data):  # Name-mangled method
            pass

2. Class Methods (cls)

Purpose: Operate on the class itself, rather than on individual instances.

  • Naming: Use snake_case (e.g., from_config, load_from_checkpoint).

  • Decorator: @classmethod

  • Example:

    class Model:
        @classmethod
        def from_config(cls, config):  # Class method
            return cls(**config)

3. Static Methods (No self or cls)

Purpose: Utility functions that don’t modify the instance or class.

  • Naming: Use snake_case (e.g., normalize_data, sigmoid).

  • Decorator: @staticmethod

  • Example:

    class Model:
        @staticmethod
        def sigmoid(x):  # Static method
            return 1 / (1 + np.exp(-x))

4. Helper Functions (Inside or Outside Class)

Purpose: Internal-use methods that aid class functionality.

  • Naming: Use **_single_underscore** if internal (e.g., _compute_gradient).

  • Example (Inside Class):

    class Model:
        def _compute_gradient(self, x):  # Helper method
            return x * 0.1
  • Example (Outside Class, Standalone Function):

    def compute_loss(y_true, y_pred):  # Standalone helper function
        return ((y_true - y_pred) ** 2).mean()

5. Dunder (Double Underscore) Methods

Purpose: Customize built-in behaviors (__init__, __call__, __getitem__, etc.).

  • Naming: Always use double underscores before and after (e.g., __call__, __repr__).

  • Example:

    class Model:
        def __init__(self, name):
            self.name = name
    
        def __call__(self, x):  # Makes object callable
            return x * 2
    
        def __repr__(self):
            return f"Model(name={self.name})"

Summary Table

Method Type Naming Style Example Notes
Instance Method snake_case train(self, data) Uses self
Private Instance Method _underscore _preprocess(self, data) Conventionally private
Name-Mangled Method __double_underscore __compute_loss(self, data) Avoid unless needed
Class Method snake_case from_config(cls, config) Uses @classmethod
Static Method snake_case sigmoid(x) Uses @staticmethod
Helper Function snake_case _compute_gradient(x) Internal use
Dunder Method __double_underscore__ __call__(self, x) Built-in behavior

Conclusion

Using consistent naming conventions for Python methods enhances readability and maintainability. By following these best practices, you can write cleaner, more understandable object-oriented code. πŸš€

Would you like to see an expanded example of a full class using these principles? Let me know! 😊