Python Factory Method: Create Shapes by Type String

A factory method that maps a type string to a concrete shape class and returns an instance, with runtime error handling.

Easy Python 3.9+ Aug 9, 2026 OOP & classes 12 views 0 copies

Python code

43 lines
Python 3.9+
class Shape:
    def draw(self):
        raise NotImplementedError


class Circle(Shape):
    def draw(self):
        return "Drawing a circle"


class Square(Shape):
    def draw(self):
        return "Drawing a square"


class Triangle(Shape):
    def draw(self):
        return "Drawing a triangle"


class ShapeFactory:
    @staticmethod
    def create(shape_type):
        shape_type = shape_type.strip().lower()
        shapes = {
            "circle": Circle,
            "square": Square,
            "triangle": Triangle,
        }
        try:
            return shapes[shape_type]()
        except KeyError:
            raise ValueError(f"Unknown shape type: {shape_type}")


if __name__ == "__main__":
    factory = ShapeFactory()
    for name in ["circle", "square", "triangle", "hexagon"]:
        try:
            shape = factory.create(name)
            print(shape.draw())
        except ValueError as e:
            print(e)

Output

stdout
Drawing a circle
Drawing a square
Drawing a triangle
Unknown shape type: hexagon

How it works

The factory pattern centralizes object creation logic in one place. ShapeFactory.create normalizes the input by stripping whitespace and lowercasing, then looks up the class in a dictionary. This avoids long if-elif chains and makes adding new shapes as simple as adding a new class and a dictionary entry. Raising a ValueError for unknown types gives clear feedback at runtime, and the NotImplementedError in the base Shape enforces that subclasses implement draw.

Common mistakes

  • Forgetting to normalize input (stem casing or whitespace) leading to KeyError
  • Raising KeyError instead of converting it to a more descriptive exception

Variations

  1. Use a class-level registry dict and `__init_subclass__` to auto-register shapes.
  2. Create a module-level function `create_shape(shape_type)` instead of a static method.

Real-world use cases

  • Game engines instantiate enemies or items based on a string from level data.
  • Serialization libraries deserialize different object types from JSON type tags.
  • Plugin systems load modules by name from configuration files at runtime.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.