HOWTO · Python

Python Class Factory

This tutorial discusses Class Factories in Python.

On this page

A class factory is a callable that creates and returns a class object. Calling the factory does not create an instance; it gives you a class that can be instantiated afterward. This distinction is useful when the definition of a class depends on configuration that is available only while a program is running.

Most Python programs should define a regular class at module level. That is the clearest option when the class is fixed and is used in one predictable way. Use a factory when a caller needs a tailored class, such as one with a selected default, a generated name, or methods assembled from a small configuration. Keep the factory focused: returning many unrelated class shapes can make types difficult to understand and test.

This tutorial shows a nested class definition and Python’s three-argument type() form. Both techniques return a class object. The nested-class approach is usually easier to read; type() is helpful when the class name, base classes, or namespace must be supplied dynamically.

How to Create a Class Factory in Python

A class factory has two calls in its normal use. First, call the factory and save the returned class. Second, call that returned class to create an object. For example, Ball = create_ball_class() assigns a class to Ball, while Ball("green") constructs a Ball instance.

The class keyword creates the class when Python executes the function body. The type(name, bases, namespace) form also creates a class at that point: name is a string, bases is a tuple of parent classes, and namespace maps attribute names to values or functions. Functions placed in the namespace become instance methods when accessed through an instance.

Choose names and constructor arguments that make the returned class unsurprising. If each factory call produces a distinct class, instances from separate calls do not share the same class identity, even if their definitions look identical. That can matter for isinstance() checks, serialization, and debugging. If you need one stable public type, define it once with normal class syntax and pass configuration to its instances instead.

Use the class Keyword to Create a Class Factory in Python

Put a class definition inside a function and return the class name. The nested class can use values from the factory’s scope, which makes this pattern practical for small configuration choices. In this example, the factory returns Ball; the instance stores the color that was passed to its constructor.

def create_ball_class():
    class Ball:
        def __init__(self, color):
            self.color = color

        def get_color(self):
            return self.color

    return Ball


Ball = create_ball_class()
ball = Ball("green")
print(ball.get_color())

The returned class behaves like any other class, so its methods and attributes are available on the instance.

green

For a factory that accepts configuration, validate it before returning the class or in the generated constructor. Validation makes an invalid input fail at a documented boundary instead of allowing an unusable object to circulate. The following boundary case rejects an empty color and handles the exception so that the program has deterministic output.

def create_ball_class(default_color):
    class Ball:
        def __init__(self, color=default_color):
            if not color:
                raise ValueError("color must not be empty")
            self.color = color

    return Ball


Ball = create_ball_class("")
try:
    Ball()
except ValueError as error:
    print(error)
color must not be empty

This factory closes over default_color, so each returned class remembers the value provided for that particular call. That is convenient for small, immutable settings. Avoid closing over mutable shared objects unless shared state is intentional; otherwise, one instance can unexpectedly affect another. If the setting belongs to every instance but should remain easy to inspect, assigning it as a class attribute is another option.

Use the Three-Argument type() Built-In to Create a Class Factory in Python

Python’s built-in type() can construct a class directly at runtime. Its three-argument form, type(name, bases, namespace), takes a class-name string, a tuple of base classes, and a dictionary that supplies the class namespace. The namespace dictionary contains class attributes; a function stored under "get_color", for example, is used as an instance method. A direct call is concise when all of those pieces are already data, but helper functions defined beside it remain module-level names.

def init(self, color):
    self.color = color


def get_color(self):
    return self.color


Ball = type(
    "Ball",
    (object,),
    {"__init__": init, "get_color": get_color},
)
ball = Ball("green")
print(ball.get_color())
green

Encapsulate the helper functions in a factory when they are implementation details and when the factory must return a configured runtime class. The code below has the same observable behavior, while init and get_color are scoped to the factory rather than added to the module namespace.

def create_ball_class(class_name):
    def init(self, color):
        self.color = color

    def get_color(self):
        return self.color

    return type(
        class_name,
        (object,),
        {"__init__": init, "get_color": get_color},
    )


Ball = create_ball_class("Ball")
ball = Ball("green")
print(Ball.__name__)
print(ball.get_color())
Ball
green

Use this approach when the name, inheritance tuple, or set of attributes is genuinely data-driven. For a static class, ordinary class syntax gives better readability, type-checker support, and tracebacks. Whichever approach you choose, test the returned class by constructing an instance and exercising the behavior a caller needs, rather than only checking that the factory returned a value.