How to dynamically create a class?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Python lets you create classes at runtime, which is useful when type definitions depend on configuration, schemas, or plugin metadata that is not known until the program starts. The usual tool is the built-in type constructor, though for many real projects the harder question is not how to do it, but whether a dynamically created class is genuinely better than a normal class or a dataclass.
Create a Class With type
The three-argument form of type creates a new class object from a name, a tuple of base classes, and a dictionary of attributes.
The resulting Person behaves like any other Python class. You can instantiate it, subclass it, inspect it, and call its methods normally.
Use Named Functions Instead of Large Lambdas
You can put lambdas in the attribute dictionary, but named functions are usually a better choice. They give clearer tracebacks, are easier to test, and make the class definition less cryptic.
This matters because dynamic class creation is already harder to read than a normal class statement. If the methods are also anonymous one-liners, the code becomes fragile quickly.
A good rule is:
- keep the dynamic part focused on assembling the class
- keep method bodies as ordinary functions
- avoid hiding business logic inside the
type(...)call itself
That keeps the design understandable even when the class name or field list is determined at runtime.
Build Classes From Runtime Configuration
A common use case is schema-driven object creation. For example, you may receive a list of required fields from a configuration file and want a lightweight model class for each schema.
This approach is useful in small frameworks, adapters, and plugin systems where the field set changes with runtime input.
Dynamic Inheritance and Mixins
You can also choose base classes dynamically. That is helpful when capabilities are optional and configured at runtime.
The mechanism is simple, but the design can become confusing if too many combinations exist. Dynamic inheritance is best when the set of possible bases is small and deliberate.
Consider make_dataclass for Data-Carrying Types
If the generated class is mostly a container for fields, dataclasses.make_dataclass is often more maintainable than raw type.
This gives you an initializer, representation, and comparison behavior without manually wiring every method. It is often the better answer when the dynamic part is just the field list.
Common Pitfalls
The most common mistake is using dynamic classes when a normal class would be clearer. Runtime class creation is powerful, but it increases cognitive load and makes tooling support weaker.
Another issue is treating runtime-generated attributes as if they were validated automatically. If the class is built from external configuration, you still need to validate field names, defaults, and method behavior.
Debugging can also get harder if methods are defined inline with lambdas or if several different classes share the same helper functions without clear naming.
Finally, metaclasses are often mentioned in discussions like this, but they solve a broader class-creation problem. If you only need to create one or two runtime-defined classes, type or make_dataclass is usually enough.
Summary
- Use
type(name, bases, attrs)to create a class dynamically at runtime. - Keep method bodies as normal functions so the generated class stays readable.
- Dynamic classes are useful for schema-driven and plugin-style designs.
- Prefer
make_dataclasswhen the class mainly holds data fields. - Choose dynamic class creation only when the runtime flexibility is worth the added complexity.
Related reading
- How to easily remember Red-Black Tree insert and delete?
- How to efficiently calculate a row in pascal's triangle?
- How to efficiently check if a list of consecutive numbers is missing any elements
- How to efficiently compare two unordered lists not sets?
- How to dynamically load a Python class
- How to efficiently compare two unordered lists not sets?
- How to efficiently compute average on the fly moving average?
- How to efficiently determine if a set of points contains two that are close

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.